In the following code, both options seem to allocate the same resource
func Allocate(v interface{}) error {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return errors.New("Value of v is nil")
}
s0 := reflect.New(rv.Type().Elem())
s1 := reflect.New(rv.Elem().Type())
return errors.New(fmt.Sprintf("What's the diff? %v %v", s0, s1))
}
If there's no difference in this specific example, an example illustrating the difference will be great. Also what's the preferable option in this specific case when trying to allocate for an interface.
Edit: reflect.DeepEqual(s0, s1) returns false. I think rv.Elem().Type() has a problem dealing with zero values so maybe rv.Type().Elem() is preferred.
Playground
Difference: Data element contains the business and technical information about a field. It contains Data type, length, field labels. Data element can contain a domain within it for type and length information instead of 'built-in type' and we can also associate search help with Data Element.
There are many mechanical differences, with one clear difference being that inline engines have a crankshaft running from front to back along the bottom center of the engine. In contrast, V engines have a crankshaft that runs from side to side in the upper part of the engine.
The key difference is that v-if conditionally renders elements and v-show conditionally displays elements. This means that v-if will actually destroy and recreate elements when the conditional is toggled. Meanwhile, v-show will always keep the element in the DOM and will only toggle its display by changing its CSS.
There are different types of finite elements. These are mainly classified based on geometrical dimensions (1D, 2D & 3D), you can further add types based on element order, other or miscellaneous types. Refer Figure 1 for types of elements: In case of 1D elements one of the dimensions is very large compare to other two dimensions.
There is no difference if v
is a non-nil pointer type.
s := "hello"
rv := reflect.ValueOf(&s)
fmt.Println(rv.Type().Elem() == rv.Elem().Type()) // prints "true"
Here are some examples where rv.Type().Elem()
and rv.Elem().Type())
are different:
// nil pointer
var p *string
rv := reflect.ValueOf(p)
fmt.Println(rv.Type().Elem()) // prints "string"
fmt.Println(rv.Elem().Type()) // panic: call of reflect.Value.Type on zero Value
// interface value
var i interface{} = "hello"
rv := reflect.ValueOf(&i).Elem()
fmt.Println(rv.Type()) // prints "interface {}"
fmt.Println(rv.Elem().Type()) // prints "string"
fmt.Println(rv.Type().Elem()) // panic: Elem of invalid type
If rv.Type().Elem()
is used in Allocate
, then the nil check can be removed and the function will work with nil pointer values.
The call reflect.DeepEqual(s0, s1)
returns false because the ptr fields in the values are different. DeepEqual
compares unsafe pointers as simple values, not as pointers. This example might help explain what's going on:
v := "hello"
rv := reflect.ValueOf(&v)
s0 := reflect.New(rv.Type().Elem())
s1 := reflect.New(rv.Elem().Type())
s2 := reflect.New(rv.Type().Elem())
s3 := reflect.New(rv.Elem().Type())
fmt.Println(reflect.DeepEqual(s0, s1)) // prints "false"
fmt.Println(reflect.DeepEqual(s0, s2)) // prints "false"
fmt.Println(reflect.DeepEqual(s1, s3)) // prints "false"
fmt.Println(reflect.DeepEqual(s2, s3)) // prints "false"
fmt.Println(reflect.DeepEqual(s0.Interface(), s1.Interface())) // prints "true"
fmt.Println(reflect.DeepEqual(s0.Interface(), s2.Interface())) // prints "true"
fmt.Println(reflect.DeepEqual(s1.Interface(), s3.Interface())) // prints "true"
fmt.Println(reflect.DeepEqual(s2.Interface(), s3.Interface())) // prints "true"
As you can see, the reflect.Value comparisons are all false, even when created using the same sequence of calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With