I don't understand why the pointer s is nil even after the input() method initialised it. Any idea?
package main
import "fmt"
type ps string
func(s *ps)input(){
x := ps("a")
s = &x
}
func(s *ps)output(){
}
func main() {
var v *ps
v.input()
if v == nil{
fmt.Println("v shouldn't be nil")
}
}
Playground http://play.golang.org/p/jU2hoMP7TS
You need two things--main needs to allocate space for a ps that input can write into, which you can do by replacing var v *ps with v := new(ps). The string will be "", but it doesn't matter what it is, just that there's space set aside in memory for a string header that input can write to. As Momer said, otherwise the pointer's nil and your program panics trying to dereference it.
And in order to assign through a pointer, input needs to use *s = x. Since *s is, informally, "get what s points to", you can read that as "change what s points to to x". Usually the automatic ref/deref behavior around the dot operator and method calls saves you from that, but when you assign through a pointer type or do other operations (arithmetic, indexing, etc.) the dereference needs to be there in the code.
v value (0) is passed into v.input. Passed value is stored in a local variable s. s value is modified. No one is saving new s value back into v.
If you want something modified in your function, you must pass pointer to the value. (or reference for slices, maps and so on).
If you want to change pointer value, you should pass pointer to your pointer.
Alex
Related
I'm struggling trying to figure out how to "extract" an integer value from a interface that holds a value whose dynamic type is pointer to integer.
You may follow this ready-to-run example in order to fully get the picture of what is problem and my intention.
TD;DR:
For some reason the reflection on a first call to reflect.ValueOf(value) over an interface whose dynamic type is pointer to integer, it returns a value whose Kind() results in reflect.Ptr, when i extract again the "inner" value using reflect.ValueOf(value).Elem() i get another value whose Kind() results in reflect.Struct. I don't even code any struct, but they appears by their own "magically". So golang may not panic but i don't understand what is happening, probably i lack of some information. I would be very thankful with anyone that explaint me what is going on.
This may work for this case, but it doesn't enlight me. I would expect to have an integer value "behind" the pointer. I don't need to access for modification, i only need to get it.
It's struct because when you call ToCompliantValue inside the function, you're not passing it the value itself, you're passing a reflect.Value value, and reflect.Value is a struct. You have to handle it directly instead of trying to use recursion:
v := reflect.ValueOf(value)
fmt.Printf("Value is %+v\n", v)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
// ...
Working example: https://play.golang.org/p/ndRjXJfj5xV
I started learning golang a couple of days ago and found reflect.Valueof() and Value.Elem() quite confusing. What is the difference between this two function/methods and how to use them correctly?
Both function/methods return a Value, and according to the go doc
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.
I found this code from a post on stackoverflow but still don't understand when to use .Elem()
func SetField(obj interface{}, name string, value interface{}) error {
// won't work if I remove .Elem()
structValue := reflect.ValueOf(obj).Elem()
structFieldValue := structValue.FieldByName(name)
if !structFieldValue.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("Cannot set %s field value", name)
}
structFieldType := structFieldValue.Type()
// won't work either if I add .Elem() to the end
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return fmt.Errorf("Provided value %v type %v didn't match obj field type %v",val,val.Type(),structFieldType)
}
structFieldValue.Set(val)
return nil
}
reflect.ValueOf() is a function, think of it as the entry point to reflection. When you have a "non-reflection" value, such as a string or int, you can use reflect.ValueOf() to get a reflect.Value descriptor of it.
Value.Elem() is a method of reflect.Value. So you can only use this if you already have a reflect.Value. You may use Value.Elem() to get the value (reflect.Value) pointed by the value wrapped by the original reflect.Value. Note that you may also use reflect.Indirect() for this. There's another "use case" for Value.Elem(), but it's more "advanced", we return to it at the end of the answer.
To "leave" reflection, you may use the general Value.Interface() method, which returns you the wrapped value as an interface{}.
For example:
var i int = 3
var p *int = &i
fmt.Println(p, i)
v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer
v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i's value: 3
This will output (try it on the Go Playground):
0x414020 3
0x414020
3
For a great introduction to Go's reflection, read The Go Blog: The Laws of Reflection. Although if you're just starting with Go, I'd focus on other things and leave reflection for a later adventure.
Another use case for Value.Elem()
This is kind of an advanced topic, so don't freak out if you don't understand it. You don't need to.
We saw how Value.Elem() can be used to "navigate" when a pointer is wrapped in the reflect.Value. Doc of Value.Elem() says:
Elem returns the value that the interface v contains or that the pointer v points to.
So if reflect.Value wraps an interface value, Value.Elem() may also be used to get the concrete value wrapped in that interface value.
Interfaces in Go is its own topic, for the internals, you may read Go Data Structures: Interfaces by Russ Cox. Again, not necessarily a topic for Go starters.
Basically whatever value you pass to reflect.ValueOf(), if it's not already an interface value, it will be wrapped in an interface{} implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}. This second "use case" surfaces if you pass a pointer to interface (which is otherwise very rare in Go!).
So if you pass a pointer to interface, this pointer will be wrapped in an interface{} value. You may use Value.Elem() to get the pointed value, which will be an interface value (not a concrete value), and using Value.Elem() again on this will give you the concrete value.
This example illustrates it:
var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader
v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type()) // *os.File
v2 := reflect.ValueOf(&r) // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type()) // *io.Reader
fmt.Println(v2.Elem().Type()) // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File
Try it on the Go Playground.
I am pulling in some data from a db - and I have a pointer to a float32 - because if I use a pointer - then I am able to check if it is nil (which it quite often might be).
When it is not nil, I want to get the value - how do I dereference it so I can get the actual float32? I can't actually find a link for that anywhere! I know exactly what I want to do, and I just can't find the syntax in Go, which I am still very new to - all help appreciated.
I know how to dereference the pointer if it is a straight float32...
but if I have the following struct...
type MyAwesomeType struct{
Value *float32
}
Then after I do :
if myAwesomeType.Value == nil{
// Handle the error later, I don't care about this yet...
} else{
/* What do I do here? Normally if it were a straight float32
* pointer, you might just do &ptr or whatever, but I am so
* confused about how to get this out of my struct...
*/
}
The Go Programming Language Specification
Address operators
For an operand x of pointer type *T, the pointer indirection *x
denotes the variable of type T pointed to by x. If x is nil, an
attempt to evaluate *x will cause a run-time panic.
Use the * operator. For example,
package main
import "fmt"
type MyAwesomeType struct {
Value *float32
}
func main() {
pi := float32(3.14159)
myAwesomeType := MyAwesomeType{Value: &pi}
if myAwesomeType.Value == nil {
// Handle the error
} else {
value := *myAwesomeType.Value
fmt.Println(value)
}
}
Playground: https://play.golang.org/p/8URumKoVl_t
Output:
3.14159
Since you are new to Go, take A Tour of Go. The tour explains many things, including pointers.
Pointers
Go has pointers. A pointer holds the memory address of a value.
The type *T is a pointer to a T value. Its zero value is nil.
var p *int
The & operator generates a pointer to its operand.
i := 42
p = &i
The * operator denotes the pointer's underlying value.
fmt.Println(*p) // read i through the pointer p
*p = 21 // set i through the pointer p
This is known as "dereferencing" or "indirecting".
Unlike C, Go has no pointer arithmetic.
I would like to append to a slice using only reflection. But I can't figure out how to "replace" the value of a with the new slice.
func main() {
fmt.Println("Hello, playground")
a := []string {"a","b","c"}
values := []string {"d","e"}
v := reflect.ValueOf(a)
fmt.Printf("%t\n\n", v.Type())
fmt.Printf("%t\n\n", v.Type().Elem().Kind())
for _, val := range values {
v.Set(reflect.Append(v, reflect.ValueOf(val)))
}
fmt.Printf("%t - %v", a, a)
}
This code is available for fiddling at https://play.golang.org/p/cDlyH3jBDS.
You can't modify the value wrapped in reflect.Value if it originates from a non-pointer. If it would be allowed, you could only modify a copy and would cause more confusion. A slice value is a header containing a pointer to a backing array, a length and a capacity. When you pass a to reflect.ValueOf(), a copy of this header is made and passed, and any modification you could do on it could only modify this header-copy. Adding elements (and thus changing its length and potentially the pointer and capacity) would not be observed by the original slice header, the original would still point to the same array, and would still contain the same length and capacity values. For details see Are Golang function parameter passed as copy-on-write?; and Golang passing arrays to the function and modifying it.
You have to start from a pointer, and you may use Value.Elem() to obtain the reflect.Value descriptor of the pointed, dereferenced value. But you must start from a pointer.
Changing this single line in your code makes it work:
v := reflect.ValueOf(&a).Elem()
And also to print the type of a value, use the %T verb (%t is for bool values):
fmt.Printf("%T\n\n", v.Type())
fmt.Printf("%T\n\n", v.Type().Elem().Kind())
// ...
fmt.Printf("%T - %v", a, a)
Output (try it on the Go Playground):
Hello, playground
*reflect.rtype
reflect.Kind
[]string - [a b c d e]
For a deeper understanding of Go's reflection, read the blog post: The Laws of Reflection
And read related questions+answers:
Assigning a value to struct member through reflection in Go
Changing pointer type and value under interface with reflection
Using reflection SetString
What's the cleanest way to handle a case such as this:
func a() string {
/* doesn't matter */
}
b *string = &a()
This generates the error:
cannot take the address of a()
My understanding is that Go automatically promotes a local variable to the heap if its address is taken. Here it's clear that the address of the return value is to be taken. What's an idiomatic way to handle this?
The address operator returns a pointer to something having a "home", e.g. a variable. The value of the expression in your code is "homeless". if you really need a *string, you'll have to do it in 2 steps:
tmp := a(); b := &tmp
Note that while there are completely valid use cases for *string, many times it's a mistake to use them. In Go string is a value type, but a cheap one to pass around (a pointer and an int). String's value is immutable, changing a *string changes where the "home" points to, not the string value, so in most cases *string is not needed at all.
See the relevant section of the Go language spec. & can only be used on:
Something that is addressable: variable, pointer indirection, slice indexing operation, field selector of an addressable struct, array indexing operation of an addressable array; OR
A composite literal
What you have is neither of those, so it doesn't work.
I'm not even sure what it would mean even if you could do it. Taking the address of the result of a function call? Usually, you pass a pointer of something to someone because you want them to be able to assign to the thing pointed to, and see the changes in the original variable. But the result of a function call is temporary; nobody else "sees" it unless you assign it to something first.
If the purpose of creating the pointer is to create something with a dynamic lifetime, similar to new() or taking the address of a composite literal, then you can assign the result of the function call to a variable and take the address of that.
In the end you are proposing that Go should allow you to take the address of any expression, for example:
i,j := 1,2
var p *int = &(i+j)
println(*p)
The current Go compiler prints the error: cannot take the address of i + j
In my opinion, allowing the programmer to take the address of any expression:
Doesn't seem to be very useful (that is: it seems to have very small probability of occurrence in actual Go programs).
It would complicate the compiler and the language spec.
It seems counterproductive to complicate the compiler and the spec for little gain.
I recently was tied up in knots about something similar.
First talking about strings in your example is a distraction, use a struct instead, re-writing it to something like:
func a() MyStruct {
/* doesn't matter */
}
var b *MyStruct = &a()
This won't compile because you can't take the address of a(). So do this:
func a() MyStruct {
/* doesn't matter */
}
tmpA := a()
var b *MyStruct = &tmpA
This will compile, but you've returned a MyStruct on the stack, allocated sufficient space on the heap to store a MyStruct, then copied the contents from the stack to the heap. If you want to avoid this, then write it like this:
func a2() *MyStruct {
/* doesn't matter as long as MyStruct is created on the heap (e.g. use 'new') */
}
var a *MyStruct = a2()
Copying is normally inexpensive, but those structs might be big. Even worse when you want to modify the struct and have it 'stick' you can't be copying then modifying the copies.
Anyway, it gets all the more fun when you're using a return type of interface{}. The interface{} can be the struct or a pointer to a struct. The same copying issue comes up.
You can't get the reference of the result directly when assigning to a new variable, but you have idiomatic way to do this without the use of a temporary variable (it's useless) by simply pre-declaring your "b" pointer - this is the real step you missed:
func a() string {
return "doesn't matter"
}
b := new(string) // b is a pointer to a blank string (the "zeroed" value)
*b = a() // b is now a pointer to the result of `a()`
*b is used to dereference the pointer and directly access the memory area which hold your data (on the heap, of course).
Play with the code: https://play.golang.org/p/VDhycPwRjK9
Yeah, it can be annoying when APIs require the use of *string inputs even though you’ll often want to pass literal strings to them.
For this I make a very tiny function:
// Return pointer version of string
func p(s string) *string {
return &s
}
and then instead of trying to call foo("hi") and getting the dreaded cannot use "hi" (type string) as type *string in argument to foo, I just wrap the argument in a call to to p():
foo(p("hi"))
a() doesn't point to a variable as it is on the stack. You can't point to the stack (why would you ?).
You can do that if you want
va := a()
b := &va
But what your really want to achieve is somewhat unclear.
At the time of writing this, none of the answers really explain the rationale for why this is the case.
Consider the following:
func main() {
m := map[int]int{}
val := 1
m[0] = val
v := &m[0] // won't compile, but let's assume it does
delete(m, 0)
fmt.Println(v)
}
If this code snippet actually compiled, what would v point to!? It's a dangling pointer since the underlying object has been deleted.
Given this, it seems like a reasonable restriction to disallow addressing temporaries
guess you need help from More effective Cpp ;-)
Temp obj and rvalue
“True temporary objects in C++ are invisible - they don't appear in your source code. They arise whenever a non-heap object is created but not named. Such unnamed objects usually arise in one of two situations: when implicit type conversions are applied to make function calls succeed and when functions return objects.”
And from Primer Plus
lvalue is a data object that can be referenced by address through user (named object). Non-lvalues include literal constants (aside from the quoted strings, which are represented by their addresses), expressions with multiple terms, such as (a + b).
In Go lang, string literal will be converted into StrucType object, which will be a non-addressable temp struct object. In this case, string literal cannot be referenced by address in Go.
Well, the last but not the least, one exception in go, you can take the address of the composite literal. OMG, what a mess.