Do we have something same as Java and C# Object in Golang? - go

In Java and C#, the Object class is implicitly parent of all classes that are defined. Is there something similar in go?

There is no inheritance in Go.
I think you are looking for interface: Go: What's the meaning of interface{}?
but if you need something similar to Object (not Class) you may use interface:
Variables of interface type also have a distinct dynamic type, which
is the concrete type of the value assigned to the variable at run time
(unless the value is the predeclared identifier nil, which has no
type). The dynamic type may vary during execution but values stored in
interface variables are always assignable to the static type of the
variable.
var x interface{} // x is nil and has static type interface{}
var v *T // v has value nil, static type *T
x = 42 // x has value 42 and dynamic type int
x = v // x has value (*T)(nil) and dynamic type *T
and:
Interface types:
An interface type specifies a method set called its interface. A
variable of interface type can store a value of any type with a method
set that is any superset of the interface. Such a type is said to
implement the interface. The value of an uninitialized variable of
interface type is nil.
see: http://golang.org/doc/go_spec.html

Related

golang make struct T implement I but not *T

I have a struct T that implements an interface I, but I want *T to not implement the interface. Is this possible?
That is, this should compile fine:
var obj I = T{}
but this should generate a compile error:
var obj I = &T{}
The reason is that it is a common mistake in my codebase to accidentally use *T as a certain interface I when it is expected that only T will be used.
Not possible. From the spec (emphasis mine):
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T).

Go type assert nil to pointer type [duplicate]

This question already has an answer here:
Convert nil interface to pointer of something in Golang?
(1 answer)
Closed 7 years ago.
Why can't I type-assert a nil to a pointer type? What is the logic behind this?
package main
func main() {
var s interface{} = nil
var p *string = nil
var q *string = s.(*string)
_ = q
_ = p
}
You can't type assert something with no type.
The static type (or just type) of a variable is the type given in its
declaration, the type provided in the new call or composite literal,
or the type of an element of a structured variable. Variables of
interface type also have a distinct dynamic type, which is the
concrete type of the value assigned to the variable at run time
(unless the value is the predeclared identifier nil, which has no
type). The dynamic type may vary during execution but values stored in
interface variables are always assignable to the static type of the
variable.
Straight from the spec (emphasis mine)
Interfaces know the type of the underlying value. For instance if I have a interface with a type MyType it can't be type asserted to *string either. You could perhaps convert its type with some work, but type assertion and type conversion are different.
Also take a look here
For an expression x of interface type and a type T, the primary
expression
x.(T)
asserts that x is not nil and that the value stored in x is of
type T. The notation x.(T)

Address of composite literal used as interface

The address of a composite literal is evaluated as the literal itself when used as an interface. Can somebody please point to the part of the ref spec which deals with this ?
package main
import "fmt"
type ntfc interface {
rx() int
}
type cncrt struct {
x int
}
func (c cncrt) rx() int{
return c.x
}
func rtrnsNtfca() ntfc {
return &cncrt{3}
}
func rtrnsNtfc() ntfc {
return cncrt{3}
}
func rtrnsCncrt() *cncrt {
return &cncrt{3}
}
func main() {
fmt.Println(rtrnsNtfca().rx())
fmt.Println(rtrnsNtfc().rx())
fmt.Println(rtrnsCncrt().rx())
}
Also here. For future ref., is it acceptable to just link to the playground without including the code here?
Spec: Method sets:
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T).
So the method set of *cncrt includes the methods set of cncrt. Since rx() is an element of cncrt's method set, it will also be in *cncrt's method set. Which means both cncrt and *cncrt types implement the ntfc interface.
If you have a pointer value (*cncrt) and you call rx() on it, the pointer will automatically be dereferenced which will be the receiver of the rx() method.
In your rtnsNtfca() and rtnsNtfc() functions an interface value of ntfc will automatically be created and returned. Interface values in Go are represented as (type;value) pairs (for more details: The Laws of Reflection #The representation of an interface). So both rtnsNtfca() and rtnsNtfc() return an interface value, but the first one holds a dynamic value of type *cncrt and the latter one holds a dynamic value of type cncrt.
And your 3rd method rtrnsCncrt() returns a concrete type (*cncrt), there is no interface wrapping involved there.
Note: "The other way around"
Spec: Calls:
If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().
This means if you would have declared rx() to have a pointer receiver, and you have a variable of type cncrt (note: not pointer), you could still call the rx() method on it if it is addressable, and the address would be taken automatically and used as the receiver.

Go: Variable to a function, returning an interface

In Go, why can I not have a variable to a function, which returns an interface type?
Here's a minimal test case:
type DummyInterface interface {
Method(string) string
}
// Dummy implements the DummyInterface interface
type Dummy struct{}
func (d Dummy) Method(i string) string {
return i
}
// DummyFunc returns a Dummy pointer (which implements the DummyInterface interface)
var DummyFunc (func() *Dummy) = func() *Dummy {
a := Dummy{}
return &a
}
// DummyInterfaceFunc is declared as returning function returning an object which implements DummyInterface -- it
// is set to DummyFunc, which does return a conforming object
var DummyInterfaceFunc (func() DummyInterface) = DummyFunc
This fails to compile (Playground example here), stating:
cannot use DummyFunc (type func() *Dummy) as type func() DummyInterface in assignment
Yet, as you can see, a *Dummy does implement DummyInterface.
Why is this?
Because *Dummy is not the same type as DummyInterface. The rule that you can assign an object to something of an interface type that object implements only applies in that literal case. If the interface type appears in one of the parameters of a type (i.e. the return type of a function), assignment is not possible.
Refer to the assignability rules for more information.
Assignability
A value x is assignable to a variable of type T ("x is assignable to
T") in any of these cases:
x's type is identical to T.
x's type V and T have identical underlying types and at least one of V or T is not a named type.
T is an interface type and x implements T.
x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not
a named type.
x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
x is an untyped constant representable by a value of type T.
This is a similar concept to: Can I convert a []T to an []interface{}?
Basically func() *Dummy is a different type from func() DummyInterface, and conversion between them is not possible.
You will need to use the interface throughout to make the function signature the same.

What is the difference between type conversion and type assertion?

What is the main differences between :
v = t.(aType) // type assertion
v = aType(t) // type conversion
Where should I use type assertion or type conversion ?
A type assertion asserts that t (an interface type) actually is a aType and t will be an aType; namely the one wrapped in the t interface. E.g. if you know that your var reader io.Reader actually is a *bytes.Buffer you can do var br *bytes.Buffer = reader.(*bytes.Buffer).
A type conversion converts one (non-interface) type to another, e.g. a var x uint8 to and int64 like var id int64 = int64(x).
Rule of thumb: If you have to wrap your concrete type into an interface and want your concrete type back, use a type assertion (or type switch). If you need to convert one concrete type to an other, use a type conversion.
tl;dr x.(T) asserts that the dynamic value of interface x is T at run time; T(x) converts the type of an expression x to some other type.
Type Assertion
You know that in Go an interface is basically a method set specification, and you can assign to an interface variable any value whose type implements that method set1.
The type assertion written x.(T) asserts that the value stored in the interface x is of type T. You use a type assertion when you want to unbox that value.
One of the most common uses is when you have interface{} and you need to retrieve the concrete value it stores. A typical example, Context values:
func foo(ctx context.Context) {
s := ctx.Value("my_key").(string) // signature is `Value(key interface{}) interface{}`
// do something with s...
}
It is called assertion because at compile time it is not known whether x actually holds the concrete type T, but you assert that it does. That's why the unchecked assertion y := x.(T) panics if x doesn't actually hold a T — you must use the comma-ok assignment v, ok := x.(T) to avoid it.
ctx = context.WithValue(ctx, "my_key", "foo")
s := ctx.Value("my_key").(int) // panic
v, ok := ctx.Value("my_key").(string)
fmt.Println(v, ok) // "foo" true
In addition, when T in x.(T) is an interface itself, the assertion checks that the value stored in x implements T. The outcome is the same as above.
Type Conversion
A type conversion written as T(x) instead "changes the type of an expression to the type specified by the conversion", i.e. changes the type of x to T. An important property of conversions is that they are statically checked2. An invalid conversion simply won't compile:
type Foo string
type Bar int
a := "foo"
fmt.Println(Bar(a)) // cannot convert a (type string) to type Bar
The main condition for a conversion to be valid is assignability between the types involved, but there's several more, including conversions between numerical types, strings and byte/rune slices, directed channels, slices and array pointers, etc.
In simple terms, you use a conversion when you already know what are the types involved, and simply want to change one to the other:
b := []byte("foo") // converts string literal to byte slice
Notes:
1: more formally, when the value's method set is a superset of the interface method set; this is also why the empty interface interface{} can hold any value, because any set is a superset of an empty set.
2: type assertions are also checked at compile time when the type T in x.(T) does not implement the interface. In practice, this won't help you catch errors when x is interface{} since all types implement it.

Resources