This question already has answers here:
Function declaration syntax: things in parenthesis before function name
(3 answers)
Closed 10 months ago.
As a Go beginner, I stumbled across code where there are brackets directly after func
func (v Version) MarshalJSON() ([]byte, error) {
return json.Marshal(v.String())
}
So what does (v Version) mean?
This is not a function but a method. In this case, it adds the MarshalJSON method to the Version struct type.
The v is the name for the received value (and would be analogous to this in a Java method or self in Python), the Version specifies the type we're adding the method to.
See go by example for, well, an example, and the specification for more details.
Related
This question already has an answer here:
Is it possible to infer type parameters from what return values are assigned to?
(1 answer)
Closed 7 months ago.
func CreateSlice[T int | string](length int) []T {
return make([]T, length)
}
Try to learn go and want to play with slices and generics . Above you can see that I want to say T can be or int or string => T int | string . Compiler say nothing about this case when I create this function , but on the moment I call it , it says cannot infer T
slices.CreateSlice(10)
Is there any restriction , or do I make some mistaces in syntax ?
The compiler cannot determine T from slices.CreateSlice(10) because T is not used as an argument. Fix by specifying T explicitly:
slices.CreateSlice[int](10) // evaluates to []int with len(10)
slices.CreateSlice[string](10) // evaluates to []string with len(10)
This question already has answers here:
How to known a function of a interface is not realized? [duplicate]
(1 answer)
Go reflection with interface embedded in struct - how to detect "real" functions?
(5 answers)
Closed 2 years ago.
So, I was trying to find the solution via the search and web-search. Wasn't successful.
This has likely a simple solution, but probably I'm just a bit messed up.
I have prepared the following example in go playground.
// main.go
type myInterface interface {
Function1() string
Function2() int
}
type notMyStruct struct {
myInterface
// arbitrary implementation
}
func myFunc(val myInterface) {
fmt.Printf("%T %v", val, val)
fmt.Printf("this failes: %q", val.Function1())
// how to safely test,
// whether the underlying value
// has implemented the interface?
}
func main() {
myFunc(¬MyStruct{})
}
It consists of an interface myInterface, an arbitrary struct notMyStruct, which has the embedded interface (but not actually implemented) and some other arbitrary fields.
Now this struct is injected into myFunc, which the go compiler will accept, due to the fact that the interface is embedded.
But if myFunc tries to call a Function of the interface, it panics – understandably.
Assuming, I don't know the actual struct implementation (because I'm not in control of the interface-implementing code):
How can I reliably test, whether a given underlying value has an actual implementation of the method set (Function1 and Function2) defined by the interface?
I assume, this is solvable with reflect package (performance is not an issue here). Maybe there's any other solutions thinkable? Type assertion didn't seem to work out for me...
This question already has answers here:
Is this casting in golang?
(1 answer)
What is the meaning of "dot parenthesis" syntax? [duplicate]
(1 answer)
Closed 4 years ago.
I recently started looking for functional go examples and I found this function:
mapper := func (i interface{}) interface{} {
return strings.ToUpper(i.(string))
}
Map(mapper, New(“milu”, “rantanplan”))
//[“MILU”, “RANTANPLAN”]
Now in this function, as you can see the return value of mapper is:
strings.ToUpper(i.(string)).
But, what does this i.(string) syntax mean? I tried searching, but didn't find anything particularly useful.
i.(string) casts (or attempts at least) i (type interface{}) to type string. I say attempts because say i is an int instead, this will panic. If that doesn't sound great to you, then you could change the syntax to
x, ok := i.(string)
In this case if i is not a string, then ok will be false and the code won't panic.
i.(string) means converting i(interface{} type) to string type.
This question already has answers here:
Convert []string to []interface{} [duplicate]
(3 answers)
Converting slice of structs to slice of empty interface [duplicate]
(1 answer)
Why can't I substitute a slice of one type for another in Go?
(3 answers)
Why can't I pass a `func() []int` as `func() []interface{}` in go?
(2 answers)
Why a slice []struct doesn't behave same as []builtin?
(3 answers)
Closed 4 years ago.
I'm trying to write a function that can take any type (more specifically, trying to get it to take any type of protobuffer, but I'll settle for being more broadly generic if I have to). Based on what I've read, it seems like it can be done like this:
func processSlice(mySlice []interface{}) void{
// Do stuff in here
}
When I try to use this with a slice of protos, though, I get the following error:
cannot use myProtoSlice (type []*MyProto) as type []interface{} in argument to processSlice
You can't cast slices from a slice of one type to another (as you can types), it would be expensive, and they decided it was better to force you to be explicit.
It would probably be less painful to simply write the function for each slice type you actually need to handle (if you know the types and there are not many).
As the error clearly depicts:
cannot use myProtoSlice (type []*MyProto) as type []interface{} in
argument to processSlice
[]interface{} of interface is not interface{} type it is different. Golang is strict about types.
Change the slice of interface to just interface to wrap the value you are receiving in your function. Modify below code:
func processSlice(mySlice []interface{}) void{
// Do stuff in here
}
To passing an interface
func processSlice(mySlice interface{}) void{
// Do stuff in here
}
This question already has answers here:
What is this "err.(*exec.ExitError)" thing in Go code? [duplicate]
(2 answers)
Closed 7 years ago.
Following is a snippet from one of the Go libs. Could anyone please point out the significance of r.(byteReader)? The syntax usage is not very obvious to a novice. byteReader is a defined interface and does not seem to be the member of io.Reader. Since, this seems to be some kind of nifty code, can anyone provide some insight.
The author mentions: "wrap it in a bufio.NewReader if it doesn't support ReadByte" pattern. https://github.com/dave-andersen/deltagolomb/blob/master/deltagolomb.go
type byteReader interface {
io.Reader
ReadByte() (c byte, err error)
}
func makeReader(r io.Reader) byteReader {
if rr, ok := r.(byteReader); ok {
return rr
}
return bufio.NewReader(r)
}
r.(byteReader) is called a type assertion. Even if io.Reader doesn't implement the byteReader interface in itself, it it still possible that the value stored in r might implement byteReader. So, by doing the type assertion, you can assert if that is the case:
The specification states:
x.(T) asserts that x is not nil and that the value stored in x is of
type T. The notation x.(T) is called a type assertion.
...
If T is
an interface type, x.(T) asserts that the dynamic type of x implements
the interface T.
Edit
The comment, "wrap it in a bufio.NewReader", refers to makeReader's provided io.Reader; if it doesn't implement byteReader, makeReader will wrap it in a bufio.Reader which does implement bytesReader, and return it instead.