type
is not a type alias, which is different than Scala for an example. The new type is not compatible, assignable or comparable to the original type. In my mind this is better than type aliasing because type aliasing, if overused, is in many cases redundant and confusing. type timeInSeconds int
and type timeInMilliSeconds int
are not compatible. You need to cast from one to the other (or just for correctness to int
and then to the other) to convert.
1
2
3
4
5
| type timeInSeconds int
type timeInMilliSeconds int
var seconds timeInSeconds = 10
var millis timeInMilliSeconds = timeInMilliSeconds(1000 * int(seconds))
|
Struct
Declaring a new type person
1
2
3
4
| type person struct {
name string
age int
}
|
Instantiating an instance of person
1
2
3
4
| a := person{
name: "Some name",
age: 10,
}
|
We can instantiate person without naming the fields, given that we provide all fields in the correct order. If we don’t provide any of the fields, i.e. use {}
we end up with an object with all its fields set to its corresponding zero value.
1
2
| a1 := person {"name 1", 1}
a2 := person {}
|
There is also the built in function new
which creates a pointer to a zero allocation of the type, thus the following two are identical
1
2
| a2 := &person {}
a3 := new(person)
|
Finally there is a notion of anonymous struct
1
2
3
4
5
| b := struct {
description string
}{
description: "This is an anonymous struct!",
}
|
Type Embedding
Let’s look at the following example using the person type we have defined earlier, we define a new type player.
1
2
3
4
5
| type player struct {
person
favouriteGame string
int
}
|
We notice that we have two anonymous fields, one of type person
and the other of type int
. The question now, how do you access those? The field names are implicit and they are the same as the type.
1
2
3
4
5
| p := player{person{"jack", 23}, "game", 1}
fmt.Println(p) // {{jack 23} game 1}
fmt.Println(p.person.name) // jack
fmt.Println(p.int) // 1
|
Go also give us another interesting feature, you can access the fields of the embedded type, person
in our case, directly using p.name
for example… just like that.
1
| fmt.Println(p.name) // jack
|
If both the embedded and the embedding type has fields holding the same name, then you will need to use p.name
for the embedding type and p.person.name
for the embedded type. Let’s redefine our type player and create an instance of it.
1
2
3
4
5
6
7
8
| type player struct {
person
favouriteGame string
int
name string
}
p := player{person{"jack", 23}, "game", 1, "Mo"}
|
As you can see we have defined name
twice. In that case the one defined in the player
struct will hide the one from person
struct.
1
2
3
4
| fmt.Println(p) // {{jack 23} game 1 Mo}
fmt.Println(p.person.name) // jack
fmt.Println(p.name) // Mo
fmt.Println(p.int) // 1
|
Notes:
- we can perform conversion from one struct to the other if they have the same exact fields.
- Anonymous struct doesn’t require explicit conversion, if types are identical.
- Field order is part of a type. Different field orders means different types, even if the fields are identical.
- If we are trying to access a field in a pointer to a struct, we don’t need to explicitly use
*
to get to the contents of that structs, we can use .
directly. That is the following two lines of codes will print the exact same thing
1
2
| fmt.Println(b.description)
fmt.Println((&b).description)
|
Pointers
- Everything in Go is pass by value.
- Pointers is for pass by reference.
- We use
&
similar to C to get the address of a var. - We use
*
similar to C again to get the value that a pointer is pointing to.
Constants
- Constants have a parallel type system, they could have a
type
or a kind
! iota
is an interesting concept, the simplest use for it is to create an enum like constants with incremental value.iota
can be used for different increments and even with the shift operator iota
1
2
3
4
5
| const (
c0 = iota // c0 == 0
c1 = iota // c1 == 1
c2 = iota // c2 == 2
)
|
Which can also be written as
1
2
3
4
5
| const (
c0 = iota // c0 == 0
c1 // c1 == 1
c2 // c2 == 2
)
|
Resources
- Ultimate Go Programming
- The Go Programming Language
- Go Documentation
- A tour of Go
- Go wiki: Switch
- The Go Programming Language Specification
- Go by Example
Comments powered by Disqus.