结构体是用户定义的类型,表示若干个字段的集合。有时应该把数据整合在一起,而不是让这些数据没有联系。Go 语言中没有类的概念,结构体就像是类的一种简化形式。
package main
import (
"fmt"
)
type Employee struct {
firstName, lastName string
age, salary int
}
func main() {
//creating structure using field names
emp1 := Employee{
firstName: "Sam",
age: 25,
salary: 500,
lastName: "Anderson",
}
//creating structure without using field names
emp2 := Employee{"Thomas", "Paul", 29, 800}
fmt.Println("Employee 1", emp1)
fmt.Println("Employee 2", emp2)
fmt.Println("emp2 age:", emp2.age)
emp2.age = 30
fmt.Println("emp2 new age:", emp2.age)
}
当定义好的结构体并没有被显式地初始化时,该结构体的字段将默认赋为其类型的零值。
package main
import (
"fmt"
)
func main() {
emp3 := struct {
firstName, lastName string
age, salary int
}{
firstName: "Andreah",
lastName: "Nikola",
age: 31,
salary: 5000,
}
fmt.Println("Employee 3", emp3)
}
package main
import (
"fmt"
)
type Employee struct {
firstName, lastName string
age, salary int
}
func main() {
emp8 := &Employee{"Sam", "Anderson", 55, 6000}
fmt.Println("First Name:", (*emp8).firstName)
fmt.Println("Age:", emp8.age)
}
Go 语言允许我们在访问结构体字段时省略*
符号。
package main
import (
"fmt"
)
type Person struct {
string
int
}
func main() {
p := Person{"Naveen", 50}
fmt.Println(p)
fmt.Println(p.int)
}
字段可以只有类型,而没有字段名。这样的字段称为匿名字段。虽然匿名字段没有名称,但其实匿名字段的名称就默认为它的类型。
如果结构体A
中嵌套了一个结构体B
,则可以通过A.B.x
来访问B
中的变量x
。但如果是结构体中嵌套的是匿名的结构体类型字段呢?此时该匿名结构体里的字段就称为提升字段,可以用外部结构体直接访问。举例:
package main
import (
"fmt"
)
type Address struct {
city, state string
}
type Person struct {
name string
age int
Address
}
func main() {
var p Person
p.name = "Naveen"
p.age = 50
p.Address = Address{
city: "Chicago",
state: "Illinois",
}
fmt.Println("Name:", p.name)
fmt.Println("City:", p.city) //city is promoted field
}
如果外部结构体和内部嵌套结构体都包含有相同的字段名,访问时外部结构体优先。
Go 方法是作用在接收者上的一个函数,接收者是某种类型的变量。因此方法是一种特殊类型的函数。
package main
import (
"fmt"
)
type Employee struct {
name string
salary int
currency string
}
/*
displaySalary() 方法将 Employee 做为接收器类型
*/
func (e Employee) displaySalary() {
fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}
func main() {
emp1 := Employee {
name: "Sam Adolf",
salary: 5000,
currency: "$",
}
emp1.displaySalary() // 调用 Employee 类型的 displaySalary() 方法
}
如果作用在外部结构体和内部嵌套结构体上的方法有相同的方法名,访问时外部结构体优先,这就和重写一个道理,可以视外部结构体为子类。
为什么我们需要方法?使用函数不可以吗?
package main
import (
"fmt"
)
type Employee struct {
name string
age int
}
//使用值接收器的方法。
func (e Employee) changeName(newName string) {
e.name = newName
}
//使用指针接收器的方法。
func (e *Employee) changeAge(newAge int) {
e.age = newAge
}
func main() {
e := Employee{
name: "Mark Andrew",
age: 50,
}
fmt.Printf("Employee name before change: %s", e.name)
e.changeName("Michael Andrew")
fmt.Printf("\nEmployee name after change: %s", e.name)
fmt.Printf("\n\nEmployee age before change: %d", e.age)
e.changeAge(51)
fmt.Printf("\nEmployee age after change: %d", e.age)
}
指针接收器适用范围:
学习资料:https://studygolang.com/subject/2