【发布时间】:2020-03-30 01:17:52
【问题描述】:
检查切片的reflect.Kind() 时,reflect 正确地将其识别为slice,而不是存储在指针中:
package main
import (
"fmt"
"reflect"
)
type Dog struct {
Name string
Age int
}
func main() {
var dogs []Dog
rDogs := reflect.ValueOf(dogs)
fmt.Println(rDogs.Kind())
}
输出:
slice
但是,当切片存储在指针中时,reflect.Kind() 将其标识为struct:
package main
import (
"fmt"
"reflect"
)
type Dog struct {
Name string
Age int
}
func main() {
dogs1 := make([]Dog, 0)
pointer := &dogs1
printPointerValueKind(pointer)
var dogs2 []Dog
pointer = &dogs2
printPointerValueKind(pointer)
}
func printPointerValueKind(pointer interface{}) {
if pointer != nil {
rPointer := reflect.ValueOf(pointer)
if rPointer.Kind() == reflect.Ptr {
value := rPointer.Elem()
rValue := reflect.ValueOf(value)
fmt.Println(rValue.Kind())
}
}
}
输出:
struct
struct
我的问题是:
为什么会这样?
有没有办法将切片存储在指针中,并且仍然让
reflect.Kind()将其识别为slice?
【问题讨论】:
-
@mkopriva 我明白了,所以回答 #1。那么#2甚至可能吗?
-
@mkopriva 谢谢!这回答了我的问题!您能否将其添加为答案,以便我接受?
-
我认为你再次得到了错误问题的正确答案。请参阅godoc.org/github.com/jmoiron/sqlx#Select,它说
dest必须“成为一个切片”:您应该编写var dogs1 []Dog,然后用&dogs1调用Select,而Select将填写Dogs1。你做了很多不必要的工作...... -
(顺便说一句,如果我是对的,这是XY problem 的经典示例。)
-
@torek 是的,
Select()适用于切片甚至结构,但我们希望在我们的项目中强制我们将只使用切片,特别是那些已使用make()初始化的切片。