zoukankan      html  css  js  c++  java
  • GO入门——6. struct与方法

    1 struct

    • Go 中的struct与C中的struct非常相似,并且Go没有class
    • 使用 type struct{} 定义结构,名称遵循可见性规则
    • 支持指向自身的指针类型成员
    • 支持匿名结构,可用作成员或定义成员变量
    • 匿名结构也可以用于map的值
    • 可以使用字面值对结构进行初始化
    • 允许直接通过指针来读写结构成员
    • 相同类型的成员可进行直接拷贝赋值
    • 支持 == 与 !=比较运算符,但不支持 > 或 <
    • 支持匿名字段,本质上是定义了以某个类型名为名称的字段
    • 嵌入结构作为匿名字段看起来像继承,但不是继承
    • 可以使用匿名字段指针
    
    //声明结构类型
    type Person struct {
    	Name string
    	Age  int
    }
    
    //包含匿名结构并作为内部成员变量
    type FullPerson struct {
    	Name    string
    	Age     int
    	Contact struct {
    		Phone, City string
    	}
    }
    
    //匿名字段名结构
    type NoFiledName struct {
    	string
    	int
    }
    
    //嵌入结构
    type in struct {
    	A string
    }
    type out struct {
    	in
    	Name string
    }
    
    func funcStruct() {
    	//初始化时可以使用p :=&Person{},实现初始化和获取指针
    	//一般采用&Person{}这样做赋值
    	per := Person{}
    	fmt.Println(per) //{ 0},string默认空字符串,int默认0
    
    	per.Age = 25 //通过.对字段操作
    
    	//无构造函数,初始化可指定字段值
    	//Person{"ppjj", 22},可以不写字段名那就必须全部按顺序赋值
    	per = Person{
    		Name: "pj",
    		Age:  24, //结尾都需要逗号
    	}
    	fmt.Println(per) //{pj 24}
    
    	//struct的函数传入是值传递
    	A := func(p Person) {
    		p.Age = 10
    		fmt.Println(p) //{pj 10}
    	}
    	A(per)
    	fmt.Println(per) //{pj 24},函数中执行的结果并不会修改per
    	//使用指针实现对struct的引用传递
    	B := func(p *Person) {
    		p.Age = 20     //指针struct可以用.直接操作
    		fmt.Println(p) //&{pj 20}
    	}
    	B(&per)
    	fmt.Println(per) //{pj 20},函数中传入的是地址,因此此处值也修改了
    	//匿名结构
    	a := &struct {
    		Name string
    		Age  int
    	}{
    		Name: "pj",
    		Age:  25,
    	}
    	fmt.Println(a) //&{pj 25}
    
    	//包含匿名结构的成员变量
    	fp := &FullPerson{}
    	fmt.Println(fp) //&{ 0 { }}
    	fp = &FullPerson{Name: "pj", Age: 25}
    	fp.Contact.Phone = "187" //匿名结构成员变量只能通过这种方式进行初始化
    	fp.Contact.City = "zz"
    	fmt.Println(fp) //&{pj 25 {187 zz}}
    
    	////匿名字段名结构,初始化时必须按定义的顺序
    	nfn := &NoFiledName{"pj", 12}
    	fmt.Println(nfn) //&{pj 12}
    
    	//嵌入结构
    	o := &out{Name: "pj", in: in{A: "in"}}
    	fmt.Println(o) //&{{in} pj}
    	o.Name = "ppjj"
    	o.A = "in1"
    	fmt.Println(o) //&{{in1} ppjj}
    	o.in.A = "in2"	
    	//两种访问方式,如果两个结构有重名字段则被加入的将被隐藏,只能通过o.in.A这样访问
    	fmt.Println(o) //&{{in2} ppjj}
    }
    
    

    2 方法

    • Go 中虽没有class,但依旧有method
    • 通过显示说明receiver来实现与某个类型的组合
    • 只能为同一个包中的类型定义方法
    • Receiver 可以是类型的值或者指针
    • 不存在方法重载
    • 可以使用值或指针来调用方法,编译器会自动完成转换
    • 从某种意义上来说,方法是函数的语法糖,因为receiver其实就是
      方法所接收的第1个参数(Method Value vs. Method Expression)
    • 如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法
    • 类型别名不会拥有底层类型所附带的方法
    • 方法可以调用结构中的非公开字段
    type AA struct {
    	Name string
    }
    type BB struct {
    	Name string
    }
    
    //接收者为AA,值传递
    func (a AA) Print(name string) {
    	a.Name = "ppjj"
    	fmt.Println(a.Name + name)
    
    }
    //接收者为BB,引用传递
    func (a *BB) Print(name string) {
    	a.Name = "ppjj"
    	fmt.Println(a.Name + name)
    
    }
    func funcMethod() {
    	//值传递,不能修改字段
    	a := AA{Name: "pj"}
    	a.Print("test")
    	fmt.Println(a)
    	//引用传递,可以修改字段
    	b := BB{Name: "pj"}
    	b.Print("test")
    	fmt.Println(b)
    }
    
  • 相关阅读:
    决策树
    flask数据库的迁移
    flask的查询,一对多,多对多
    django的验证码
    第一讲:python环境配置(python2.7+python3.7)
    pytest
    【TS】-类型兼容性
    HTML--src和href的区别
    JS--为什么null是对象?
    JS--null和undefined的区别
  • 原文地址:https://www.cnblogs.com/suolu/p/6715650.html
Copyright © 2011-2022 走看看