结构体
type Person struct { Name string Age int}
// 使用var声明结构体变量,默认值是零值var p Person
// 使用结构体字面量p := Person{ Name: "张三", Age: 18,}
// 使用new函数,返回指针func NewPerson(name string, age int) *Person { return &Person{ Name: name, Age: age, }}
// 访问结构体成员fmt.Println(p.Name)package main
import "fmt"
type User struct { name string age int}
type News struct { title string}
func (n News) Report() { fmt.Printf("report %s\n", n.title)}
type fakeNews = News
func main() { var n1 = fakeNews{ title: "fakeNews", } n1.Report()
// 初始化结构体 // Go 没有构造函数,需要手动初始化 u1 := &User{} // u1是*User类型 u2 := User{} // u2是User类型 u3 := new(User) // u3是*User类型,Go会为其分配内存,并填充零值,然后返回其地址 var u4 User // u是User类型 var u5 *User // u5是*User类型,未分配内存,值为nil,调用方法会panic
// 字段赋值 u6 := User{ // u6是User类型,并且初始化了name和age name: "Tom", age: 10, } u7 := User{} // u7是User类型,后面再赋值 u7.name = "Tom" u7.age = 10
fmt.Printf("u1: %v\n", u1) // u1: &{ 0} fmt.Printf("u2: %v\n", u2) // u2: { 0} fmt.Printf("u3: %v\n", u3) // u3: &{ 0} fmt.Printf("u4: %v\n", u4) // u4: { 0} fmt.Printf("u5: %v\n", u5) // u5: <nil> fmt.Printf("u6: %v\n", u6) // u6: {Tom 10} fmt.Printf("u7: %v\n", u7) // u7: {Tom 10}}package main
import "fmt"
// 不定参数type Profile struct { // Id Name 是必须的 Id int Name string Address string}
type Option func(p *Profile)
func NewProfile(id int, name string, options ...Option) *Profile { p := &Profile{ Id: id, Name: name, }
for _, option := range options { option(p) } return p}
func WithAddress(address string) Option { return func(p *Profile) { p.Address = address }}
func main() { profile := NewProfile(1, "Tom", WithAddress("China")) fmt.Println(profile) // &{1 Tom China}}语法
func (接收者 接收者类型) 方法名(参数列表)返回值列表 { // 方法体}接收者类型:
- 值接收者:操作结构体的副本,不会影响原始值
- 指针接收者:操作结构体的指针,可以修改原始值
package main
import "fmt"
type BankAccount struct { AccountNumber string // 账号 AccountHolder string // 账户持有人 Balance float64 // 账户余额 IsActive bool // 账户是否激活}
func (ba BankAccount) GetAccountInfo() string { status := "活跃" if !ba.IsActive { status = "冻结" } return fmt.Sprintf("Account Number: %s, Account Holder: %s, Balance: %.2f, IsActive: %s", ba.AccountNumber, ba.AccountHolder, ba.Balance, status)}
// Deposit 存款func (ba *BankAccount) Deposit(amount float64) error { if !ba.IsActive { return fmt.Errorf("账户已冻结") } if amount <= 0 { return fmt.Errorf("存款金额必须大于0") } ba.Balance += amount return nil}
// Withdraw 取款func (ba *BankAccount) Withdraw(amount float64) error { if !ba.IsActive { return fmt.Errorf("账户已冻结") } if amount <= 0 { return fmt.Errorf("取款金额必须大于0") } if amount > ba.Balance { return fmt.Errorf("余额不足") } ba.Balance -= amount return nil}
// 冻结账号func (ba *BankAccount) Freeze() { ba.IsActive = false}
// 激活账号func (ba *BankAccount) Activate() { ba.IsActive = true}
func main() { account := BankAccount{ AccountNumber: "1234567890", AccountHolder: "张三", Balance: 1000.0, IsActive: true, }
fmt.Println(account.GetAccountInfo()) // Account Number: 1234567890, Account Holder: 张三, Balance: 1000.00, IsActive: 活跃
err := account.Deposit(500.0) if err != nil { fmt.Println(err) } fmt.Println(account.Balance) // 1500
err = account.Withdraw(200.0) if err != nil { fmt.Println(err) } fmt.Println(account.Balance) // 1300
account.Freeze() err = account.Deposit(500.0) if err != nil { fmt.Println(err) // 账户已冻结 } fmt.Println(account.Balance) // 1300}package main
import "fmt"
type rect struct { width, height int}
func (r *rect) area() int { return r.width * r.height}
func (r rect) perim() int { return 2*r.width + 2*r.height}
func main() { r := rect{width: 10, height: 5}
fmt.Println("area: ", r.area()) // area: 50 fmt.Println("perim:", r.perim()) // perim: 30
// 修改结构体的值,要使用指针来调用方法 rp := &r fmt.Println("area: ", rp.area()) // area: 50 fmt.Println("perim:", rp.perim()) // perim: 30}package main
import "fmt"
// 结构体type Fish struct {}
// 方法func (f Fish) Swim() { fmt.Println("I am swimming")}
// 定义一个新类型type FakeFish struct {}
func (f FakeFish) FakeSwim() { fmt.Println("I am swimming in the sky")}
type SeaFish struct {}
func (f SeaFish) Swim() { fmt.Println("I am swimming in the sea")}
func main() { fake := FakeFish{} //fake.Swim() // 编译错误,FakeFish 类型没有 Swim 方法 fake.FakeSwim() // I am swimming in the sky
// 类型转换,转换后可以使用 Fish 类型的方法 tk := Fish(fake) tk.Swim() // I am swimming
sf := SeaFish{} // 这里调用的是 SeaFish 的 Swim 方法 sf.Swim() // I am swimming in the sea
tk = Fish(sf) // 这里调用的是 Fish 的 Swim 方法 tk.Swim() // I am swimming}