目录
结构体--定义
type
struct_variable_type
struct {
member member_type
member member_type
......
}
go结构体中的成员可以是任意类型
例子:
type Student struct {
name string
age int //小写私有成员(对外不可见)
Class string //首字母大写则该成员为公有成员(对外可见)
}
结构体--声明与初始化
1.成员赋值形式
var stu1 Student
stu1.age = 18
stu1.name = "xiaoluo"
stu1.Class = "go"
2 new 函数创建
var stu2 *Student = new(Student)
stu2.name = "xiaoluo"
stu2.age = 20
3 &形式创建
var stu3 *Student = &Student{
name: "rose",
age: 18,
Class: "go", // 如果分行的时候每行都要,
}
4 KV 形式初始化值
var stu4 Student = Student{ // KV 形式初始化值
name: "xiaoluo",
age: 18,
Class: "Go", // 注意这里的逗号不能少
}
5 值顺序初始化
var stu5 Student = Student{ // 顺序形式 形式初始化值
"xiaoluo",
18,
"go", // 注意这里的逗号不能少
}
6 nil结构体
var stu6 *Student = nil
结构体--tag
tag可以为结构体的成员添加说明或者标签便于使用,这些说明可以通过反射获取到。
结构体中的成员首字母小写对外不可见,但是我们把成员定义为首字母大写这样与外界进行数据交互会带来极大的不便,此时tag带来了解决方法
tag --json序列化和反序列化
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
var stu = Student{Name: "xiaoluo", Age: 18}
data, err := json.Marshal(stu)
if err != nil {
fmt.Println("json encode failed err:", err)
return
}
fmt.Println("stu: ", string(data)) //{"name":"xiaoluo","age":18}
var stu2 Student
err = json.Unmarshal(data, &stu2) // 反序列化
fmt.Println("stu2: ", stu2) // {xiaoluo 18}
}
结构体--匿名成员
结构体中,每个成员不一定都有名称,也允许字段没有名字,即匿名成员。
同一种类型匿名成员只允许最多存在一个。
当匿名成员是结构体时,且两个结构体中都存在相同字段时,优先选择最近的字段。
package main
import "fmt"
type Person struct {
Name string
Age int
}
type Student struct {
score string
Age int
Person // 匿名内嵌结构体
}
func main() {
var stu = new(Student)
stu.Age = 22 //优先选择Student中的Age
fmt.Println(stu.Person.Age, stu.Age) // 0,22
}
结构体--继承、多继承
当结构体中的成员也是结构体时,该结构体就继承了这个结构体,继承了其所有的方法与属性,当然有多个结构体成员也就是多继承。
访问父结构中属性也使用“.”,但是当子结构体中存在和父结构中的字段相同时候,只能使用:"子结构体.父结构体.字段"访问父结构体中的属性,如上面示例的stu.Person.Age
继承结构体可以使用别名,访问的时候通过别名访问,如下面示例man1.job.Salary
//struct-继承、多继承
package main
import "fmt"
type Person struct {
Name string
Age int
}
type Teacher struct {
Salary int
Class string
}
type Man struct {
sex string
job Teacher //别名,继承Teacher
Person //继承Person
}
func main() {
var man1 = new(Man)
man1.Age = 18
man1.Name = "xiaoluo"
man1.job.Salary = 1
fmt.Println("man1:", man1, man1.job.Salary) //&{ {1 } {xiaoluo 18}} 1
var man2 = Man{
sex: "女",
job: Teacher{
Salary: 2,
Class: "班主任",
},
Person: Person{ // 匿名初始化方式
Name: "xiaoluo老师",
Age: 18,
},
}
fmt.Println("man2", man2) //{女 {2 班主任} {xiaoluo老师 18}}
}
结构体--方法
一个类型加上它的方法等价于面向对象中的一个类。
一个重要的区别是:在
Go
中,类型的代码和绑定在它上面的
方法的代码可以不放置在一起,它们可以存在在不同的源文件,
唯一的要求是:它们必须是同一个包的
。
定义方法
的格式
func(recv recevier_type)methodName(parameter_list)(return_value_list){}
package main
import (
"fmt"
"math"
)
type Circle struct {
x int
y int
Radius int
}
// 面积
func (c Circle) Area() float64 {
return math.Pi * float64(c.Radius) * float64(c.Radius)
}
// 周长
func (c Circle) Circumference() float64 {
return 2 * math.Pi * float64(c.Radius)
}
func (c Circle) expand() {
c.Radius *= 2
}
func (c *Circle) expand2() {
c.Radius *= 2
}
func main() {
var c = Circle{Radius: 50}
fmt.Println(c.Area(), c.Circumference())
// 指针变量调用方法形式上是一样的
var pc = &c
fmt.Println(pc.Area(), pc.Circumference())
c.expand()
fmt.Println(c.Radius) //50
c.expand2()
fmt.Println(c.Radius) //100
}
interface(接口)
Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量
interface--定义
type 接口名称 interface {
method1 (参数列表) 返回值列表
method2 (参数列表) 返回值列表
...
}
interface--使用
如果一个接口没有任何方法,我们称为空接口,由于空接口没有方法,
任意结构体都 隐式地实现了空接
要实现一个接口,
必须实现该接口里面的所有方法
。
//interface使用
package main
import "fmt"
//定义接口
type Skills interface {
Running()
Getname() string
}
type Student struct {
Name string
Age int
}
// 实现接口
func (p Student) Getname() string { //实现Getname方法
return p.Name
}
func (p Student) Running() { // 实现 Running方法
fmt.Printf("%s running\n", p.Name)
}
func main() {
var skill Skills
var stu1 Student
stu1.Name = "xiaoluo"
stu1.Age = 12
skill = stu1
skill.Running() //调用接口
fmt.Println(skill.Getname())
}
interface--空接口
go语言内置了一个空接口,名字叫interface{}
空接口里面没有方法,所以它也不具有任何能力。它可以容纳任意类型对象。比如一个字典的 key 是字符串,但是希望 value 可以容纳任意类型的对象,
// 空接口
package main
import "fmt"
func main() {
var user = map[string]interface{}{
"age": 30,
"address": "Beijing Tongzhou",
"married": true,
}
fmt.Println(user)
// 类型转换语法
var age = user["age"].(int)
var address = user["address"].(string)
var married = user["married"].(bool)
fmt.Println(age, address, married)
user["price"] = 5.5
var price = user["price"].(float64)
fmt.Println("user: ", user, price)
}