• GO开发[五]:结构体struct和方法


    Go结构体struct

    Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性。

    package main
    
    import (
    	"fmt"
    )
    //声明
    type Student struct {
    	Id int
    	Name string
    	age int
    }
    
    func main() {
    	var s Student
    	s.Id =1
    	s.Name ="greg"
    	s.age=20
    	fmt.Println(s)
    	fmt.Printf("Name:%p
    ", &s.Name)
    	fmt.Printf("Id:%p
    ", &s.Id)
    	fmt.Printf("Age: %p
    ", &s.age)
    
    	s1 := Student {
    		Id :2,
    		Name:"gregory",
    		age:20,
    	}
    	fmt.Println(s1)
    	s1=s
    	fmt.Println(s1)
    
    	var s2 *Student = &Student{
    		Id:3,
    		age:  20,
    		Name: "greg",
    	}
    	fmt.Println(s2)
    }
    

    结构体指针

    package main
    
    import "fmt"
    
    //结构体指针
    type Student struct {
       Id int
       Name string
    }
    
    func main(){
       s1 := Student{
          Id :2,
          Name:"greg",
       }
       fmt.Println(s1)
    
       var p *Student
       p = &s1
       p.Id =3
       fmt.Println(s1)
    
       var p1 *int
       p1 = &s1.Id
       *p1 = 4
       fmt.Println(s1)
    }
    

    结构体性质

    结构体是用户单独定义的类型,不能和其他类型进行强制转换

    package main
    
    import "fmt"
    
    type integer int
    
    type Student struct {
       Id int
    }
    
    type Stu Student //alias
    
    func main() {
       var i integer = 1000
       var j int = 100
       //j = i cannot use
       j = int(i)
       fmt.Println(j)
    
       var a Student
       a = Student{30}
       fmt.Println(a)
    
       var b Stu
       //a=b  cannot use
       a = Student(b) //转换
       fmt.Println(a)
    }
    

    我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的机制获取到,最常用的场景就是json序列化和反序列化。

    type student struct {
        Id int      “this is Id field”
        Name stirng  “this is name field”
    }
    

    序列化和反序列化

    package main
    
    import (
       "fmt"
       "encoding/json"
       "log"
    )
    
    type Student struct {
       Id int
       Name string
    }
    
    func main(){
       s := Student{
          Id:1,
          Name:"greg",
       }
       fmt.Println(s)
       buf,err := json.Marshal(s)
       if err != nil{
          log.Fatalf("marshal error:%s",err)
       }
       fmt.Println(string(buf))
    
    
       str := `{"Id":2,"Name":"alice"}`
       var s2 Student
       err1 := json.Unmarshal([]byte(str),&s2)
       if err1 != nil {
          log.Fatalf("unmarshal error:%s",err)
       }
       fmt.Println(s2)
    }
    //将Student map的数据写入到文件
    

    结构体中字段可以没有名字,即匿名字段

    访问匿名字段

    package main
    
    import (
       "fmt"
       "time"
    )
    
    type Student struct {
       name string
       age  int
    }
    
    type Class struct {
       Student
       name string
       int
       Start time.Time
       age  int
    }
    
    type School struct {
       Student
       Class
    }
    
    func main() {
       var t Class
       t.Student.name = "stu"
       t.Student.age = 100
    
       t.name="cls"
       t.age=80
       t.int=2000
       fmt.Println(t)
    }
    

    匿名字段冲突处理

    package main
    
    import (
       "fmt"
    )
    
    type Student struct {
       name string
       age  int
    }
    
    type Class struct {
       name string
       age  int
    }
    
    type School struct {
       Student
       Class
    }
    
    func main() {
       var t School
       t.Student.name = "stu"
       t.Class.name = "cls"
       fmt.Println(t)
    }
    

    方法

    Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct

    定义:func (recevier type) methodName(参数列表)(返回值列表){}
    

    方法调用

    package main
    
    type Point struct {
    	X, Y float64
    }
    
    func (p *Point) ScaleBy(factor float64) {
    	p.X *= factor
    	p.Y *= factor
    }
    
    func main() {
    	//直接指针
    	p := &Point{1,2}
    	p.ScaleBy(2)
    
    	//声明结构体后再用指针指向
    	p1 := Point{1,2}
    	p2 := &p1
    	p2.ScaleBy(2)
    
    	//使用结构体调用,隐式取地址
    	p3 := Point{1,2}
    	p3.ScaleBy(2) //等价于(&p3).ScaleBy(2)
    }
    

    结构体方法调用:

    package main
    
    import "fmt"
    
    type Student struct {
       Id int
       Name  string
       Age   int
       Score int
    }
    
    func (p *Student) init(name string, age int, score int) {
       p.Name = name
       p.Age = age
       p.Score = score
       fmt.Println(p)
    }
    
    func (p Student) get() Student {
       return p
    }
    
    func main() {
       var stu Student
       (&stu).init("stu", 10, 200)
    
       stu1 := stu.get()
       fmt.Println(stu1)
    }
    

    练习:两点之间的距离

    package main
    
    import (
       "fmt"
       "math"
    )
    
    type Point struct {
       X,Y float64
    }
    
    func (p Point) Distance(q Point) float64 {
       return math.Hypot(q.X-p.X, q.Y-p.Y)
    }
    
    func main() {
       p := Point{1,2}
       q := Point{4,6}
       fmt.Println(p.Distance(q))
    }
    

    方法和函数的区别:

    函数调用: function(variable, 参数列表)
    方法:variable.function(参数列表)
    

    指针receiver和值receiver:本质上和函数的值传递和地址传递是一样的

    方法的访问控制:可见性

    通过首字母大小写来控制可见性
    可见性是package级别的

    继承:

    如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。

    package main
    
    import "fmt"
    
    type Student struct {
       Id int
       name   string
    }
    
    func (p *Student) Run() {
       fmt.Println("greg")
    }
    
    type Class struct {
       Student
       golang string
    }
    
    type School struct {
       gregs Student
    }
    
    func main() {
       var c Class
       c.Id = 100
       c.name = "greg2"
       c.golang = "一班"
    
       fmt.Println(c)
       c.Run()
    
       var sch School
       sch.gregs.Id = 100
       sch.gregs.name = "train"
       fmt.Println(sch)
       sch.gregs.Run()
    }
    

    组合和匿名字段:

    ​ 如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。

    ​ 如果一个struct嵌套了另一个有名结构体,那么这个模式就叫组合。

    多重继承:如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现了多重继承。

  • 相关阅读:
    ios 数据类型转换 UIImage转换为NSData NSData转换为NSString
    iOS UI 12 block传值
    iOS UI 11 单例
    iOS UI 08 uitableview 自定义cell
    iOS UI 07 uitableviewi3
    iOS UI 07 uitableviewi2
    iOS UI 07 uitableview
    iOS UI 05 传值
    iOS UI 04 轨道和动画
    iOS UI 03 事件和手势
  • 原文地址:https://www.cnblogs.com/ningxin18/p/8353728.html
Copyright © 2020-2023  润新知