▶ 技術めも
Go 言語 02
type
適切な型を自分で用意(型のAlias)
type ID int
type Priority int
func ProcessTask(id ID, priority Priority) {
}
var id ID = 3
var priority Priority = 5
ProcessTask(priority, id) // コンパイルエラー
構造体(struct、class)
大文字で始まる場合はパブリック,小文字の場合はパッケージ内に閉じたスコープ
初期値指定がない場合はゼロ値で初期化
// Taskという型を定義
type Task struct {
ID int
Detail string
done bool
}
// 値を生成
var mytask Task = Task{
ID: 1,
Detail: "buy the milk",
done: true,
}
mytask.ID
mytask.Detail
mytask.done
// フィールド名省略
var task Task = Task{
1, "buy the milk", true,
}
構造体の名前の前に * を付けるとポインタ型になる
var mytask Task = Task{} // Task型
var mytask *Task = &Task{} // Taskのポインタ型
ポインタ型(参照渡)
構造体の名前の前に & を付けると,変数にはアドレスが格納
Taskのポインタ型は*Taskという型
func Finish(task *Task) {
task.done = true
}
task := &Task{done: false}
Finish(task)
fmt.Println(task.done) // ポインタ型からでもフィールドにアクセス可能
new()
構造体は new() を用いて初期化することもできます
すべてゼロ値で初期化しそのポインタを返します
var mytask *Task = new(Task)
mytask.ID = 1
mytask.Detail = "buy the milk"
fmt.Println(mytask.done) // false
コンストラクタ
ない
Newで始まる関数を定義しその内部で構造体を生成するのが通例
func NewTask(id int, detail string) *Task {
task := &Task{
ID: id,
Detail: detail,
done: false,
}
return task
}
mytask := NewTask(1, "buy the milk")
メソッド
func (task Task) String() string {
str := fmt.Sprintf("[%d] %s", task.ID, task.Detail)
return str
}
task := NewTask(1, "buy the milk")
fmt.Printf(“%s”, task)
値を変更する必要がある場合はポインタ渡し
func (task *Task) Finish() {
task.done = true
}
mytask := NewTask(1, "buy the milk")
mytask.Finish()
インタフェース
その型がどのようなメソッドを実装するべきかを規定する
// 宣言
type Stringer interface {
String() string
}
// 実装
func Print(stringer Stringer) {
fmt.Println(stringer.String())
}
Print(task)
型の埋め込み(継承)
構造体型宣言時に,フィールドではなく型のみを記述することで,その型を埋め込むことができる
// User 構造体
type User struct {
FirstName string
LastName string
}
func (u *User) FullName() string {
fullname := fmt.Sprintf("%s %s",
u.FirstName, u.LastName)
return fullname
}
func NewUser(firstName, lastName string) *User {
return &User{
FirstName: firstName,
LastName: lastName,
}
}
type Task struct {
ID int
Detail string
done bool
*User // Userを埋め込む
}
func NewTask(id int, detail,
firstName, lastName string) *Task {
task := &Task{
ID: id,
Detail: detail,
done: false,
User: NewUser(firstName, lastName),
}
return task
}
継承のようにメソッド呼び出しできる
task := NewTask(1, "buy the milk", "Jxck", "Daniel")
task.FirstName
task.LastName
task.FullName()
task.User
型の変換
キャストに失敗した場合はパニックが発生
var i uint8 = 3
var j uint32 = uint32(i)
var s string = "abc"
var b []byte = []byte(s)
a := int("a")
Type Assertion(型の検査)
func Print(value interface{}) {
s, ok := value.(string) // string かどうか?
if ok {
fmt.Printf("value is string: %s\n", s)
} else {
fmt.Printf("value is not string\n")
}
}
Type Switch(型による分岐)
type Stringer interface {
String() string
}
func Print(value interface{}) {
switch v := value.(type) {
case string:
fmt.Printf("value is string: %s\n", v)
case int:
fmt.Printf("value is int: %d\n", v)
case Stringer:
fmt.Printf("value is Stringer: %s\n", v)
}
}