Suppose I have a type alias like this:
type myint int;
Now I have a myint type called foo. Is there any way to convert foo from a myint to an int?
Use a conversion to convert a myint to an int:
package main
import "fmt"
type myint int
func main() {
foo := myint(1) // foo has type myint
i := int(foo) // use type conversion to convert myint to int
fmt.Println(i)
}
The type myint is a not an alias for int. It's a different type. For example, the expression myint(0) + int(1) does not compile because the operands are different types. There are two built-in type aliases in Go, rune and byte. Applications cannot define their own aliases.
Related
Spec says:
A value x is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:
x's type V and T have identical underlying types and at least one of V or T is not a defined type.
numerical type uint8 is a defined type, so with the above rule, assignability fails in the below code:
package main
type Point struct {
x uint8
y uint8
}
type Polar Point
var p Polar = Point{x: 1, y: 2}
func main() {
}
What are non-defined types in GoLang, to test the above rule?
A non-defined type is a type without an identifier assigned to them. For instance:
type S struct {
A int
}
func main() {
var s S
// You can assign a literal struct with the same underlying type to a variable of type S
s=struct{A int}{1}
}
Above, the type of struct {A int} is not a defined type.
// The underlying types of the following ones are both int.
type (
MyInt int
Age MyInt
)
// The following new types have different underlying types.
type (
IntSlice []int // underlying type is []int
MyIntSlice []MyInt // underlying type is []MyInt
AgeSlice []Age // underlying type is []Age
)
// The underlying types of []Age, Ages, and AgeSlice
// are all the non-defined type []Age.
type Ages AgeSlice
Type System Overview
I have a struct with one of it's fields being another struct and I would like to access this struct by name (as a parameter). I followed Using reflect, how do you set the value of a struct field? and it works for basic type but not for composite types.
package main
import (
"fmt"
"reflect"
)
type PntInt struct {
p *int64
}
type Foo struct {
X int64
Px PntInt
}
func main() {
foo := Foo{}
fmt.Println(foo)
i := int64(8)
Pi := PntInt{&i}
reflect.ValueOf(&foo).Elem().FieldByName("X").SetInt(i)
reflect.ValueOf(&foo).Elem().FieldByName("Px").Set(Pi)
fmt.Println(foo)
}
setting the integer works but trying to set "Px" fails with the error
./prog.go:25:52: cannot use Pi (type PntInt) as type reflect.Value in argument to reflect.ValueOf(&foo).Elem().FieldByName("Px").Set
You want to use a Value:
reflect.ValueOf(&foo).Elem().FieldByName("Px").Set(reflect.ValueOf(Pi))
Here it is running on the Go playground
See code below:
I have an odd behavior that I can't understand in Golang. If I want to create a type alias of a structure and that structure meets the requirements of a interface type, then the type alias won't meet the requirements of that interface type. I have no idea why this is happening. Any thoughts?
package main
import (
"fmt"
)
type MyInt struct {
value int
}
func (m MyInt) DoubleIt() int {
return m.value * 2
}
type MyInter interface {
DoubleIt() int
}
type MyIntContainer struct {
d MyInter
}
type MC MyIntContainer
type MI MyInt
func main() {
e1 := MyIntContainer{MyInt{12}} //This is OK
fmt.Printf("%d\n", e1.d.DoubleIt())
e2 := MC{MI{12}} //this fails with error - line 29
fmt.Printf("%d\n", e2.d.DoubleIt())
}
The error message:
Line 29: cannot use MI literal (type MI) as type MyInter in field value:
MI does not implement MyInter (missing DoubleIt method)
In your code MI is a new type which doesn't carry over the methods from the original type. The DoubleIt method really isn't available:
e2 := MI{12}
fmt.Printf("%d\n", e2.DoubleIt())
e2.DoubleIt undefined (type MI has no field or method DoubleIt)
An alternative if you want to carry over the methods would be to embed MyInt:
type MI struct {
MyInt
}
Then you can say:
e2 := MI{MyInt{12}}
fmt.Printf("%d\n", e2.DoubleIt())
From the spec:
A type may have a method set associated with it. The method set of any
other type T consists of all methods declared with receiver type T. Further rules apply to structs containing anonymous fields, as
described in the section on struct types. Any other type has an empty
method set.
In golang, structs are instantiated differently from "regular" types:
If it's a regular type: MyFloat(2)
If it's a struct: MyFloat{2}
Is there a particular reason for this?
package main
import (
"fmt"
)
type MyFloat float64
type MyFloat2 struct {
X float64
}
func main() {
f1 := MyFloat(2)
f2 := MyFloat2{3}
fmt.Println(f1)
fmt.Println(f2)
}
MyFloat(2) is a conversion. MyFloat2{3} is a composite literal.
Conversions can be used on structs:
var f3 struct {
X float64
}
f4 := MyFloat2(f3)
playground
Suppose I have a type alias like this:
type myint int;
Now I have a myint type called foo. Is there any way to convert foo from a myint to an int?
Use a conversion to convert a myint to an int:
package main
import "fmt"
type myint int
func main() {
foo := myint(1) // foo has type myint
i := int(foo) // use type conversion to convert myint to int
fmt.Println(i)
}
The type myint is a not an alias for int. It's a different type. For example, the expression myint(0) + int(1) does not compile because the operands are different types. There are two built-in type aliases in Go, rune and byte. Applications cannot define their own aliases.