我有一个包含不同变量类型的切片。一些字符串,整数等等。有什么办法可以让我去"演员"在适当的情况下,指向*interface{}
到*string
或*int32
的其中一个值的指针。
这是一个演示此问题的玩具程序:http://play.golang.org/p/J3zgrYyXPq
// Store a string in the slice
valSlice := make([]interface{}, 1)
var strVal string = "test"
valSlice[0] = strVal
// Create a pointer to that string
ptrToStr := &valSlice[0]
// Outputs "string vs *interface {}"
fmt.Printf("%T vs %T\n", valSlice[0], ptrToStr)
// Attempt 1 (doesn't compile):
// ----------------------------
// How can I cast the pointer type to (*string), referencing the same
// memory location as strVal?
// This doesn't compile:
//var castPtr *string = &valSlice[0].(string)
// Attempt 2 (after assertion, doesn't point to the same memory location):
var sureType string = valSlice[0].(string)
var castPtr *string = &sureType
*castPtr = "UPDATED"
fmt.Println(valSlice[0]) // Outputs "test", not "UPDATED"
如果我需要证明我这样做的理由,请在此解释。 database/sql
包在扫描值时会查看指针类型。我的代码已经准备了一个切片,其中包含正确类型的零值变量以匹配结果集。
因为Scan
需要指针,我迭代我的切片并构建一个指向原始切片中变量的新切片。然后我将这一段指针传递给Scan
。但是因为上面创建指针的行为导致*interface{}
指针而不是与变量类型匹配的指针,Scan
不知道转换原始[]byte
值的基础数据类型到。
答案 0 :(得分:2)
1你必须知道,当一个var被分配给一个接口时,会发生什么?
str := "hello world"
var tmp interface{} = str
编译器将创建一个tempotary对象,该对象与str
具有相同的值,并且tmp
与之关联。因此,您对tmp
所做的一切都与str
无关。但是go不允许你改变tempotary对象。所以你不能在interface
中取消引用tempotary对象而你无法改变它,这就是错误存在的原因。如果您想了解有关interface
工具的更多信息,请阅读http://research.swtch.com/interfaces
2如果要更改原始对象,请将指针传递给接口
valSlice := make([]interface{}, 1)
var strVal string = "test"
valSlice[0] = &strVal //pass a pointer to a interafce
var castPtr *string = valSlice[0].(*string) // get the pointer
*castPtr = "UPDATED"//change the string strVal
fmt.Println(strVal) // Outputs "UPDATE"