7. Type System
Contents
7. Type System¶
User-defined types¶
Go does not have classes, but it have types that support users to define their own data type. The most common way to create a new data type is by using struct.
Syntax
type <type name> struct {
...
<field name> <field type>
...
}
Here, <field type> can be of any primitive types, or a user-defined type.
There are 2 ways to initialize an object of a new type (if there is no initialization, the object’s will be assigned with zero value, i.e., 0 for numeric types, empty for string and false for boolean) [[1]].
Syntax
<type name>{<field 1 value>, <field 2 value>, ...}
or
<type name>{
<field name 1>: <value>,
<field name 2>: <value>,
...
}
To retrieve the value of the attribute, simply write the attribute after the object name, seperated by a dot ..
Syntax
<object name> = <type initialization>
<object name>.<attribute name>
Example
// struct-example.go
package main
import (
"fmt"
)
type Student struct {
name string
id string
}
func main() {
studentA := Student{"A", "001"}
studentB := Student{
name: "B",
id: "002",
}
fmt.Println(studentA)
fmt.Println(studentB)
}
You should receive the output
{A 001}
{B 002}
Below is another example of embeded data type in data type. In this example, data type StudentRecord contains a field student of Student type.
// embedding-type.go
package main
import (
"fmt"
)
type Student struct {
name string
id string
}
type StudentRecord struct {
student Student
semester string
grade float32
}
func main() {
spring_sem := StudentRecord{Student{"A", "001"}, "spring", 3.8}
fall_sem := StudentRecord{
student: Student{
name: "A",
id: "001",
},
grade: 3.78,
semester: "fall",
}
fmt.Println("student", spring_sem.student.name, "semester", spring_sem.semester, "grade", spring_sem.grade)
fmt.Println("student", fall_sem.student.name, "semester", fall_sem.semester, "grade", fall_sem.grade)
}
The output should be
student A semester spring grade 3.8
student A semester fall grade 3.78
Methods¶
Similar to class of other OOP languages such as Java, type of Go has methods associated to it. To distinguish between a method and a function, a method is a function with a receiver argument. A receiver is an argument and it is located between the function definition keyword func and the method name.
Syntax
func (<variable> <user-defined type>) <function name> (parameters) <return type>{
...
<code block>
...
<return statement>
}
The receiver is either pointer receiver or value receiver. For pointer receiver, changes applied to object’s attributes will be saved. But with value receiver, the change is ignored after the method is called. [1]
Example
// method-example.go
package main
import "fmt"
type Car struct {
color string
brand string
}
func (c *Car) changeColorWithPointerReceiver(new_color string) {
c.color = new_color
}
func (c Car) changeColorWithValueReceiver(new_color string) {
c.color = new_color
}
func main() {
BMW := Car{
color: "blue",
brand: "BMW",
}
fmt.Println("Before change")
fmt.Println(BMW)
fmt.Println("======")
fmt.Println("After applying change not using pointer")
BMW.changeColorWithValueReceiver("red")
fmt.Println(BMW)
fmt.Println("After applying change using pointer")
BMW.changeColorWithPointerReceiver("red")
fmt.Println(BMW)
}
You should receive an output
Before change
{blue BMW}
======
After change not using pointer
{blue BMW}
After change using pointer
{red BMW}
String() Method¶
There are standard methods in Go that serves similar purpose across all objects. One of them is String() method, which specifies the string representation of an object. [2]
Syntax
func (<variable> <user-defined type>) String() string{
return <string representation of the object>
}
Example
package main
import "fmt"
type Car struct {
color string
brand string
}
func (c *Car) changeColor(new_color string) {
c.color = new_color
}
func (c Car) String() string {
return fmt.Sprintf("Brand: %s, Color: %s", c.brand, c.color)
}
func main() {
BMW := Car{
color: "blue",
brand: "BMW",
}
fmt.Println("Before change")
fmt.Println(BMW)
BMW.changeColor("red")
fmt.Println("After change")
fmt.Println(BMW)
}
This method define a string representation of a Car’s object to be in the format:
Brand: <brand name>, Color: <color>
That format is featured in the return value of String() method.
The expected output of the program should be
Before change
Brand: BMW, Color: blue
After change
Brand: BMW, Color: red
Reference:¶
Go in Action - Chapter 5.1, 5.2