创建一个结构体变量后,如果没有给属性赋值,都对应一个零值(默认值)。
bool类型是false;
string类型是空字符串"",
数值类型是0,
数组类型的默认值和它的元素类型相关,比如 score [3]int 则为[0 0 0];
指针,slice, map的零值都是nil, 即还没有分配空间
不同结构体变量是独立的,互不影响,一个结构体变量字段的改变,不影响另一个
type Person struct{
Name string
Age int
}
var p1 *Person = new(Person)
(*p1).Name = "hh" // 也可以写成 p1.Name = "hh" ,底层会进行处理
(*p1).Age = 2 // *p1.Age=2这样是错的,要加括号
var p2 *Person = &Person{}
type PersonB struct{
Name string
Agw int
}
var a Person
var b PersonB
a = Person(b) // 可以转换,注意:两个结构体的属性要完全一样(属性名,属性类型,属性个数都必须一样才能转)
变量总是存在内存中的
结构体的所有属性在内存中是连续的
package main
import (
"fmt"
)
type student struct {
Name string
Age int
}
func (s *student) String() string { // 如果实现了String()方法,那么输出这个变量时,会自动调用此方法
return fmt.Sprintf("Name=%s, Age=%d\n", s.Name, s.Age)
}
func main() {
var stu = student{
"hh",
23,
}
fmt.Println(&stu) // Name=hh, Age=23
}
// src/test/model/student.go
package model
// 因为student结构体首字母是小写,因此只能在model包中使用,可以使用工厂模式解决
type student struct {
Name string
Score float64
}
func NewStudent(Name string, s float64) *student {
return &student{
Name,
s,
}
}
// -------------------
// src/test/main/main.go
package main
import (
"fmt"
"test/model"
)
func main() {
var stu = model.NewStudent("hh", 88.8)
fmt.Println(stu) // &{hh 88.8}
}
面向对象编程:继承、封装、多态
// src/test/model/person.go
package model
import "fmt"
// 封装
type person struct {
Name string
age int
sal float64
}
func NewPerson(name string) *person {
return &person{
Name: name,
}
}
func (p *person) SetAge(age int) {
if age < 0 || age > 150 {
fmt.Println("年龄有误")
return
}
p.age = age
}
func (p *person) GetAge() int {
return p.age
}
// src/test/main/main.go
package main
import (
"fmt"
"test/model"
)
func main() {
var stu = model.NewPerson("hh")
stu.SetAge(18)
fmt.Println(stu, "--", stu.GetAge()) // &{hh 18 0} -- 18
}
select {} // 这行代码的作用是实现阻塞