Reputation: 479
I have a slice that contains different variable types. Some strings, integers, etc. Is there any way for me to "cast" a pointer to one of these values from *interface{}
to *string
or *int32
where appropriate.
Here is a toy program that demonstrates the issue: 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"
If I need to justify my desire to do this, here's the explanation. The database/sql
package looks at the pointer type when scanning values. My code has already prepared a slice holding zero-valued variables of the correct types to match the resultset.
Because Scan
requires pointers, I iterate over my slice and build a new slice of pointers to the variables in my original slice. I then pass this slice of pointers into the Scan
. But because the act of creating a pointer as above results in an *interface{}
pointer instead of one that matches the variable type, the Scan
does not know the underlying datatype to convert the raw []byte
value to.
Upvotes: 0
Views: 1954
Reputation: 1694
1 You must know , when a var is assigned to a interface , what happend ?
str := "hello world"
var tmp interface{} = str
the complier will create a tempotary object , which has the same value with str
,and tmp
is associated with it. So after that , all you do to tmp
is not associated with str
. But go doesn't allow you to change the tempotary object。 So you can't have the dereference of the tempotary object in interface
and you can't change it, that's why the errors exist. If you want more information about the implements of interface
, read http://research.swtch.com/interfaces
2 If you want change the original object, pass the pointer to a interface
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"
Upvotes: 2