What is returned by Lookup in plugin package? - pointers

Here is a code block.
p, err := plugin.Open(filename)
if err != nil {
log.Fatalf("cannot load plugin %v", filename)
}
xmapf, err := p.Lookup("Map")
if err != nil {
log.Fatalf("cannot find Map in %v", filename)
}
mapf := xmapf.(func(string, string) []mr.KeyValue)
I know this code is to load a plugin and find a Map function in it. But I am confused about xmapf.(func(string, string) []mr.KeyValue). What is the type of xmapf? The golang document says it is a Symbol, A Symbol is a pointer to a variable or function. And if i'm right about the type of xmapf, why func_pointer.(signature) returns a function?

Plugin.Lookup() returns a plugin.Symbol which is simply an empty interface{} value:
type Symbol interface{}
There is no generics (yet) in Go, so this is required so you can use a single lookup function to lookup variables and functions of any type.
And you need to use a type assertion on the returned symbol to obtain a value of a concrete (or other interface) type from it.
xmapf.(func(string, string) []mr.KeyValue)
This is a type assertion, and if it holds (if xmapf is not nil and it holds a value of concrete type func(string, string) []mr.KeyValue), the result of the type assertion will be a value of that type. "That" type is a function type, so if the type assertion holds, mapf will hold a function value which you can call "directly", like
var keyValues []mr.KeyValue
keyValues = mapf("a", "b")

Related

Print a type without using reflrect and create new object

In below code, in order to show the expected type, I have to create a new object and call reflect.TypeOf on it.
package main
import (
"fmt"
"reflect"
)
type X struct {
name string
}
func check(something interface{}) {
if _, ok := something.(*X); !ok {
fmt.Printf("Expecting type %v, got %v\n",
reflect.TypeOf(X{}), reflect.TypeOf(something))
}
}
func main()
check(struct{}{})
}
Perhaps that object creation is not an overhead, but I still curious to know a better way. Are there something like X.getName() or X.getSimpleName() in java?
To obtain the reflect.Type descriptor of a type, you may use
reflect.TypeOf((*X)(nil)).Elem()
to avoid having to create a value of type X. See these questions for more details:
How to get the string representation of a type?
Golang TypeOf without an instance and passing result to a func
And to print the type of some value, you may use fmt.Printf("%T, something).
And actually for what you want to do, you may put reflection aside completely, simply do:
fmt.Printf("Expecting type %T, got %T\n", (*X)(nil), something)
Output will be (try it on the Go Playground):
Expecting type *main.X, got struct {}
Using reflects is almost always a bad choice. You can consider using one of the following ways
Use switch
If you want to control the flow depending on the type you can use the switch construction
func do(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Twice %v is %v\n", v, v*2)
case string:
fmt.Printf("%q is %v bytes long\n", v, len(v))
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
Use fmt package
If you want only to display its type you can always use the fmt package
i := 1000
fmt.Printf("The type is %T", i)

reflect.Pointer() returned value is not the value address

type BookInfo struct {
Meta *TableMeta
...
}
func (si *schemaInfo) getTabInfo(obj interface{}) (*tabInfo, error) {
typ := reflect.TypeOf(obj)
val := reflect.ValueOf(obj)
if typ.Kind() != reflect.Ptr {
return nil, errors.New("nborm.schemaInfo.getDBInfo() error: required a pointer")
}
meta := *(**TableMeta)(unsafe.Pointer(val.Pointer()))
...
}
getTabInfo() works well, but I want to know why val.Pointer() return a value of **TableMeta? Why not a *TableMeta?The document of reflect says,
Pointer returns v's value as a uintptr. It returns uintptr instead of
unsafe.Pointer so that code using reflect cannot obtain
unsafe.Pointers without importing the unsafe package explicitly. It
panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or
UnsafePointer.
In my mind:
info := &BookInfo{}
val := reflect.ValueOf(info)
ptr := val.Pointer()
meta := (*TableMeta)(unsafe.Pointer(val.Pointer()))
should work, but infact when I called val.Pointer(), the returned value is the pointer of *TableMeta(**TableMeta).
The value you have is a pointer to a BookInfo struct, it is of type *BookInfo. And the type of BookInfo.Meta field is also a pointer, it is of type *TableMeta, thus a *BookInfo can then be looked at as **TableMeta, hence the "double" pointer.
It's true that the struct pointer points to its first field, but don't build on it. It's fragile. If you add a field before it, it'll break badly (which will only happen at runtime, no compile time messages due to package unsafe).
So if the value is of type *BookInfo, simply obtain that out of the reflect.Value wrapper, then you can refer to its field like value.Meta, which will be of type *TableMeta. Avoid using package unsafe, especially if it's not needed.

Set an interface to nil in Golang

I'm trying to set an internal value of an interface to nil something like the following :
typ := &TYP{InternalState: "filled"}
setNil(typ)
fmt.Printf("Expecting that %v to be nil", typ)
And I need to know how to implement the setNil(typ interface{}) method.
For more details see this code in play.golang.org.
The thing is you don't have an interface value. You have a pointer value, a pointer to a concrete type. That is not the same as an interface value.
If you want to change the value of a variable of any type, you have to pass a pointer to it. This also includes variables of interface type, and also variables of pointer type. This is one of those very rare cases when a pointer to interface{} makes sense (*interface{}), in fact it's inevitable.
But if your function expects an interface and you pass a non-interface value, an interface value will be created implicitly and you could only nil this implicitly created value.
So we have 2 different / distinct cases:
Function to nil an interface{}
func setNilIf(v *interface{}) {
*v = nil
}
Using it:
var i interface{} = "Bob"
fmt.Printf("Before: %v\n", i)
setNilIf(&i)
fmt.Printf("After: %v\n", i)
Output:
Before: Bob
After: <nil>
So it works.
Function to nil a pointer; using unsafe
Actually this is your case. We want to change the value of a variable of pointer type. To accept a pointer to any type, we can use unsafe.Pointer. unsafe.Pointer is a language support, it's a special pointer type which can be converted from and to any pointer type.
We want to accept the address (pointer) of the pointer variable, which is something like **SomeType. To actually be able to assign a new value (nil) to the pointer variable, we have to dereference it (* operator). But unsafe.Pointer cannot be dereferenced, so first we have to convert it to a pointer to pointer to "something", but since we only want to assign nil (which is the same to all pointer types regardless of the type of the pointed value), the "something" doesn't matter, I will just use int, and so I will convert the unsafe.Pointer pointer value to **int.
func setNilPtr(p unsafe.Pointer) {
*(**int)(p) = nil
}
Using it:
typ := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %v\n", typ)
Output:
Before: &{filled}
After: <nil>
So this one also works. There is still another way using reflection:
Function to nil a pointer; using reflect
You can also nil a pointer using reflection only (reflect package). We still have to pass the address of the variable of pointer type. Note that in this case the type of the parameter will simply be interface{}. And it will contain a dynamic type like **SomeType. Since pointers have zero value nil, we can obtain such a value with reflect.Zero() which we will set using Value.Set():
func setNilPtr2(i interface{}) {
v := reflect.ValueOf(i)
v.Elem().Set(reflect.Zero(v.Elem().Type()))
}
Using it:
typ2 := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %v\n", typ2)
Output:
Before: &{filled}
After: <nil>
So this one also works. Try these on the Go Playground.
But seriously: if you want to nil something, assign nil to it. Do not complicate things unnecessarily.
i = nil
typ = nil

How to force passing parameter as a pointer in Go?

I am implementing an application layer network protocol which uses JSON in Go.
func ReadMessage(conn net.Conn, returnMessage interface{}) bool {
messageBytes := // read from conn
error := json.Unmarshal(messageBytes, &returnMessage)
if error != nil {
return false
}
return true
}
The function takes a struct as its second parameter where the message is unmarshalled. The function can be called like this:
msg := MessageType1{}
ok := ReadMessage(conn, &msg)
Or without the ampersand (&)
msg := MessageType1{}
ok := ReadMessage(conn, msg)
which will compile, but not do what is should as the struct is passed as a copy, not as a reference and the original msg will remain empty. So I'd like to force passing the struct by reference and catch this error at compile time.
Changing the parameter type to *interface{} will not compile:
cannot use &msg (type *MessageType1) as type *interface {} in function argument:
*interface {} is pointer to interface, not interface
Is there some Go style way of doing this correctly?
There is not a way to do this in the function declaration.
You can use reflection though and panic at runtime when the argument is not a pointer.
However maybe you should consider changing the design of your code. The concrete type of the argument should not matter. It either implements the interface you need or not.
Demo: http://play.golang.org/p/7Dw0EkFzbx
Since Go 1.18 you can do this using generics:
func test[T any](dst *T) {
//Do something with dst
}
You can't enforce this as *T always has the method set of T. Thus both implement the interface.
From the spec:
The method set of any other type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T).
What you can do instead is to use the language's ability to return multiple values in your function, as Volker already stated:
func ReadMessage(conn net.Conn) (interface{}, bool) {
var returnMessage interface{}
messageBytes := // read from conn
error := json.Unmarshal(messageBytes, &returnMessage)
if error != nil {
return nil, false
}
return returnMessage, true
}
You should also consider not returning type interface{} but some meaningful type.

Replace wrapping struct with a type declaration in Go

I want to extend the regexp from the Go standard library to be able to define my own methods. I use the following struct:
type RichRegexp struct {
*regexp.Regexp
}
As you can see, this struct contains nothing but the wrapped regexp.Regexp. So I wonder whether I could replace this with a simple type declaration like this:
type RichRegexp regexp.Regexp
But how should I write the following func then?
func Compile(expression string) (*RichRegexp, error) {
regex, err := regexp.Compile(expression)
if err != nil {
return nil, err
}
return &RichRegexp{regex}, nil // How to do this?
}
I tried to convert regexp.Regexp to my RichRegexp but it didn't compile. What is the general pattern to return a custom type which wraps a underlying type?
You can use a conversion, but in this case it is necessary, that your type definition is not a pointer:
type MyRegexp *regexp.Regexp // Doesn't work
This is backed by the spec:
The receiver type must be of the form T or *T where T is a type name.
The type denoted by T is called the receiver base type; it must not be
a pointer or interface type and it must be declared in the same
package as the method. The method is said to be bound to the base type
and the method name is visible only within selectors for that type.
However, you can do this:
type MyRegexp regexp.Regexp
As you're handling values now, you can do the following:
x := regexp.MustCompile(".*")
y := MyRegexp(*x)
And you have your own regexp type.
Full code at play: http://play.golang.org/p/OWNdA2FinN
As a general pattern, I would would say:
If it's unlikely to change and you don't need to store arbitrary values, use
a type conversion.
If you need to store values along with your embedded type, use a struct.
If your code is likely to change and needs to support large varieties of things,
define an interface and don't use embedding / type conversion.
package main
import (
"regexp"
)
type RichRegexp regexp.Regexp
func Compile(expression string) (*RichRegexp, error) {
regex, err := regexp.Compile(expression)
if err != nil {
return nil, err
}
return (*RichRegexp)(regex), nil
}
func main() {
Compile("foo")
}
Also here: http://play.golang.org/p/cgpi8z2CfF

Resources