我怎样才能"演员" Go中的指针类型是否匹配指向值的类型?

时间:2014-09-16 01:05:57

标签: go

我有一个包含不同变量类型的切片。一些字符串,整数等等。有什么办法可以让我去"演员"在适当的情况下,指向*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值的基础数据类型到。

1 个答案:

答案 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"