怎么样通过反射reflect向slice追加元素或让这个slice指向另外一个slice

anlitylee · 2019-06-07 18:30:25 · 1304 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2019-06-07 18:30:25 的主题,其中的信息可能已经有所发展或是发生改变。

本人接触go不久,遇到一个问题,还请解惑,通过网上搜索很多对反射的描述都是针对struct的,没怎么看到有针对slice的,希望能得到答案,谢谢

type User struct {
    Id int
    Name string
}

func ChangeSlice(s interface{}) {
    user1 := User{
        Id: 1,
        Name: "张三",
    }
    newSlice := make([]User, 0)
    newSlice = append(newSlice, user1)
    // 这样写是不对的,这里不知道该怎么写了
    s = &newSlice
}

func main() {
    var users []User
    ChangeSlice(&users)
    // 这里希望让Users指向ChangeSlice函数中的那个新数组
    fmt.Println(users)  // 希望输出[{1  张三}],但是现在输出[]
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1304 次点击  
加入收藏 微博
3 回复  |  直到 2019-06-09 11:22:07
StoneFlying
StoneFlying · #1 · 6年之前
package main

import ( 
    "fmt" 
)

type User struct {
    Id int
    Name string
}

func ChangeSlice(s interface{}) {
    user1 := User{
        Id: 1,
        Name: "张三",
    }
    newSlice := make([]User, 0)
    newSlice = append(newSlice, user1)
    *(s.(*[]User)) = newSlice
}

func main() {
    users := make([]User, 0)
    ChangeSlice(&users)
    // 这里希望让Users指向ChangeSlice函数中的那个新数组
    fmt.Println(users)  // 希望输出[{1  张三}],但是现在输出[]
}
anlitylee
anlitylee · #2 · 6年之前

非常感谢,你的代码没有问题,确实可行!可能是我没有表述清楚,实际上我是想通过反射的方式,而不是断言! 通过搜索,我找到了一个解决方案

package main

import (
    "fmt"
    "reflect"
    "os"
)

type User struct {
    Id int
    Name string
}

func ChangeSlice(s interface{}) {
    sT := reflect.TypeOf(s)
    if sT.Kind() != reflect.Ptr {
        fmt.Println("参数必须是ptr类型")
        os.Exit(-1)
    }
    sV := reflect.ValueOf(s)
    // 取得数组中元素的类型
    sEE := sT.Elem().Elem()
    // 数组的值
    sVE := sV.Elem()

    // new一个数组中的元素对象
    sON := reflect.New(sEE)
    // 对象的值
    sONE := sON.Elem()
    // 给对象复制
    sONEId := sONE.FieldByName("Id")
    sONEName := sONE.FieldByName("Name")
    sONEId.SetInt(10)
    sONEName.SetString("李四")

    // 创建一个新数组并把元素的值追加进去
    newArr := make([]reflect.Value, 0)
    newArr = append(newArr, sON.Elem())

    // 把原数组的值和新的数组合并
    resArr := reflect.Append(sVE, newArr...)

    // 最终结果给原数组
    sVE.Set(resArr)
}

func main() {
    users := make([]User, 0)
    ChangeSlice(&users)
    // 这里希望让Users指向ChangeSlice函数中的那个新数组
    fmt.Println(users)
}
anlitylee
anlitylee · #3 · 6年之前
StoneFlyingStoneFlying #1 回复

```go package main import ( "fmt" ) type User struct { Id int Name string } func ChangeSlice(s interface{}) { user1 := User{ Id: 1, Name: "张三", } newSlice := make([]User, 0) newSlice = append(newSlice, user1) *(s.(*[]User)) = newSlice } func main() { users := make([]User, 0) ChangeSlice(&users) // 这里希望让Users指向ChangeSlice函数中的那个新数组 fmt.Println(users) // 希望输出[{1 张三}],但是现在输出[] } ```

感谢回复!!

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传