zoukankan      html  css  js  c++  java
  • Go结构体

    1. 结构体的定义和初始化

    package main
    
    import "fmt"
    
    func main() {
    	/*
    	   结构体:是由一系列具有相同类型或不同类型的数据构成的数据集合
    	       结构体成员是由一系列的成员变量构成,这些成员变量也被称为“字段”
    	*/
    	
    	//1.方法一
    	var p1 Person
    	fmt.Println(p1) // { 0  }
    	p1.name = "王二狗"
    	p1.age = 30
    	p1.sex = "男"
    	p1.address = "北京市"
    	fmt.Printf("姓名:%s,年龄:%d,性别:%s,地址:%s
    ",p1.name,p1.age,p1.sex,p1.address)
    
    	//2.方法二
    	p2 := Person{}
    	fmt.Println(p2) // { 0  }
    	p2.name = "Ruby"
    	p2.age = 28
    	p2.sex= "女"
    	p2.address = "上海市"
    	fmt.Printf("姓名:%s,年龄:%d,性别:%s,地址:%s
    ",p2.name,p2.age,p2.sex,p2.address)
    
    	//3.方法三
    	p3 := Person{name :"如花",age :20,sex:"女",address:"杭州市"}
    	fmt.Println(p3)
    	p4 := Person{
    		name:"隔壁老王",
    		age : 40,
    		sex :"男",
    		address:"武汉市",
    	}
    	fmt.Println(p4)
    
    	//4.方法四
    	p5 := Person{"李小花",25,"女","成都"}
    	fmt.Println(p5)
    }
    
    //1.定义结构体
    //Person是类型,这个类型有一个大的分类叫结构体
    type Person struct {
    	name string
    	age int
    	sex string
    	address string
    }

     2. 结构体指针

    package main
    
    import "fmt"
    
    func main() {
    	/*
    	数据类型:
    		值类型:int,float,bool,string,array,struct
    
    		引用类型:slice,map,function,pointer
    
    
    	通过指针:
    		new(),不是nil,空指针
    			指向了新分配的类型的内存空间,里面存储的零值。
    	 */
    	 //1.结构体是值类型
    	 p1 := Person{"王二狗",30,"男","北京市"}
    	 fmt.Println(p1)
    	 fmt.Printf("%p,%T
    ",&p1,p1)
    
    	 p2 := p1
    	 fmt.Println(p2)
    	 fmt.Printf("%p,%T
    ",&p2,p2)
    
    	 p2.name = "李小花"
    	 fmt.Println(p2)
    	 fmt.Println(p1)
    
    	 //2.定义结构体指针
    	 var pp1 *Person
    	 pp1 = &p1
    	 fmt.Println(pp1)
    	 fmt.Printf("%p,%T
    ",pp1,pp1)
    	 fmt.Println(*pp1)
    
    	//(*pp1).name = "李四"
    	pp1.name = "王五"
    	fmt.Println(pp1)
    	fmt.Println(p1)
    
    	//使用内置函数new(),go语言中专门用于创建某种类型的指针的函数
    	pp2 := new(Person)
    	fmt.Printf("%T
    ",pp2)
    	fmt.Println(pp2)
    	//(*pp2).name
    	pp2.name = "Jerry"
    	pp2.age = 20
    	pp2.sex = "男"
    	pp2.address= "上海市"
    	fmt.Println(pp2)
    
    	pp3 := new(int)
    	fmt.Println(pp3)
    	fmt.Println(*pp3)
    }
    type Person struct {
    	name string
    	age int
    	sex string
    	address string
    }
    
    package main
    
    import "fmt"
    
    // 构造函数
    
    type person struct {
    	name string
    	age  int
    }
    
    type dog struct {
    	name string
    }
    
    // 构造函数:约定成俗用new开头
    // 返回的是结构体还是结构体指针
    // 当结构体比较大的时候尽量使用结构体指针,减少程序的内存开销
    // 把一个地址拷贝多次也不会有多大的内存开销
    func newPerson(name string, age int) *person {
    	return &person{
    		name: name,
    		age:  age,
    	}
    }
    
    func newDog(name string) dog {
    	return dog{
    		name: name,
    	}
    }
    
    func main() {
    	p1 := newPerson("yang", 18)
    	p2 := newPerson("mo", 9000)
    	fmt.Println(p1, p2)
    	d1 := newDog("yang")
    	fmt.Println(d1)
    }

    3. 匿名字段模拟继承

    package main
    
    import "fmt"
    
    func main() {
    	/*
    	匿名结构体和匿名字段:
    
    	匿名结构体:没有名字的结构体,
    		在创建匿名结构体时,同时创建对象
    		变量名 := struct{
    			定义字段Field
    		}{
    			字段进行赋值
    		}
    
    	匿名字段:一个结构体的字段没有字段名
    
    
    	匿名函数:
    
    	 */
    	s1 := Student{name:"张三",age:18}
    	fmt.Println(s1.name,s1.age) //张三 18
    
    	func (){
    		fmt.Println("hello world...") //hello world...
    	}()
    
    	s2 := struct{
    		name string
    		age int
    	}{
    		name:"李四",
    		age:19,
    	}
    	fmt.Println(s2.name,s2.age) //李四 19
    
    	//w1 := Worker{name:"王二狗",age:30}
    	//fmt.Println(w1.name,w1.age)
    
    
    	w2 := Worker{"李小花",32}
    	fmt.Println(w2) //{李小花 32}
    	fmt.Println(w2.string) //李小花
    	fmt.Println(w2.int) //32
    }
    
    type Worker struct {
    	//name string
    	//age int
    	string //匿名字段
    	int //匿名字段,默认使用数据类型作为名字,那么匿名字段的类型就不能重复,否则会冲突
    	//string
    }
    
    type Student struct {
    	name string
    	age int
    }

    结构体的匿名字段:

    可以用字段来创建结构,这些字段只包含一个没有字段名的类型。这些字段被称为匿名字段。

    在类型中,使用不写字段名的方式,使用另一个类型

    type Human struct {
        name string
        age int
        weight int
    } 
    type Student struct {
        Human // 匿名字段,那么默认Student就包含了Human的所有字段
        speciality string
    } 
    func main() {
        // 我们初始化一个学生
        mark := Student{Human{"Mark", 25, 120}, "Computer Science"}
        // 我们访问相应的字段
        fmt.Println("His name is ", mark.name)
        fmt.Println("His age is ", mark.age)
        fmt.Println("His weight is ", mark.weight)
        fmt.Println("His speciality is ", mark.speciality)
        // 修改对应的备注信息
        mark.speciality = "AI"
        fmt.Println("Mark changed his speciality")
        fmt.Println("His speciality is ", mark.speciality)
        // 修改他的年龄信息
        fmt.Println("Mark become old")
        mark.age = 46
        fmt.Println("His age is", mark.age)
        // 修改他的体重信息
        fmt.Println("Mark is not an athlet anymore")
        mark.weight += 60
        fmt.Println("His weight is", mark.weight)
    }

    可以使用"."的方式进行调用匿名字段中的属性值

    实际就是字段的继承

    其中可以将匿名字段理解为字段名和字段类型都是同一个

    基于上面的理解,所以可以mark.Human = Human{"Marcus", 55, 220} mark.Human.age -= 1

    若存在匿名字段中的字段与非匿名字段名字相同,则最外层的优先访问,就近原则

    通过匿名访问和修改字段相当的有用,但是不仅仅是struct字段哦,所有的内置类型和自定义类型都是可以作为匿名字段的。

    4. 结构体嵌套

    package main
    
    import "fmt"
    
    func main() {
    	/*
    	结构体嵌套:一个结构体中的字段,是另一个结构体类型。
    		has a
    	 */
    
    	b1 := Book{}
    	b1.bookName = "西游记"
    	b1.price = 45.8
    
    	s1 := Student{}
    	s1.name = "王二狗"
    	s1.age = 18
    	s1.book = b1  //值传递
    	fmt.Println(b1)
    	fmt.Println(s1)
    	fmt.Printf("学生姓名:%s,学生年龄:%d,看的书是:《%s》,书的价格是:%.2f
    ",s1.name,s1.age,s1.book.bookName,s1.book.price)
    
    
    	s1.book.bookName = "红楼梦"
    	fmt.Println(s1)
    	fmt.Println(b1)
    
    
    	b4 := Book{bookName:"呼啸山庄",price:76.9}
    	s4 := Student2{name:"Ruby",age:18,book:&b4}
    	fmt.Println(b4)
    	fmt.Println(s4)
    	fmt.Println("	",s4.book)
    
    	s4.book.bookName = "雾都孤儿"
    	fmt.Println(b4)
    	fmt.Println(s4)
    	fmt.Println("	",s4.book)
    
    
    	s2 := Student{name:"李小花",age:19,book:Book{bookName:"Go语言是怎样炼成的",price:89.7}}
    	fmt.Println(s2.name,s2.age)
    	fmt.Println("	",s2.book.bookName,s2.book.price)
    
    	s3 := Student{
    		name:"Jerry",
    		age:17,
    		book:Book{
    			bookName:"十万个为啥",
    			price:55.9,
    		},
    	}
    	fmt.Println(s3.name,s3.age)
    	fmt.Println("	",s3.book.bookName,s3.book.price)
    }
    
    //1.定义一个书的结构体
    type Book struct {
    	bookName string
    	price float64
    }
    
    //2.定义学生的结构体
    type Student struct {
    	name string
    	age int
    	book Book
    }
    
    type Student2 struct {
    	name string
    	age int
    	book *Book // book的地址
    }
    

    5. 结构体OOP

    package main
    
    import "fmt"
    
    func main() {
    	/*
    	面向对象:OOP
    
    	Go语言的结构体嵌套:
    		1.模拟继承性:is - a
    			type A struct{
    				field
    			}
    			type B struct{
    				A //匿名字段
    			}
    
    		2.模拟聚合关系:has - a
    			type C struct{
    				field
    			}
    			type D struct{
    				c C //聚合关系
    			}
    	 */
    
    	 //1.创建父类的对象
    	 p1 := Person{name:"张三",age:30}
    	 fmt.Println(p1)
    	 fmt.Println(p1.name,p1.age)
    
    	 //2.创建子类的对象
    	s1 := Student{Person{"李四",17},"千锋教育"}
    	fmt.Println(s1)
    
    	s2 :=Student{Person:Person{name:"rose",age:19},school:"北京大学"}
    	fmt.Println(s2)
    
    	var s3 Student
    	s3.Person.name = "王五"
    	s3.Person.age = 19
    	s3.school = "清华大学"
    	fmt.Println(s3)
    
    	//提升字段
    	s3.name = "Ruby"
    	s3.age = 16
    	fmt.Println(s3)
    
    	fmt.Println(s1.name,s1.age,s1.school)
    	fmt.Println(s2.name,s2.age,s2.school)
    	fmt.Println(s3.name,s3.age,s3.school)
    /*
    s3.Person.name---->s3.name
    Student结构体将Person结构体作为一个匿名字段了
    那么Person中的字段,对于Student来讲,就是提升字段
    Student对象直接访问Person中的字段
     */
    
    
    }
    //1.定义父类
    type Person struct {
    	name string
    	age int
    }
    
    //2.定义子类
    type Student struct {
    	Person //模拟继承结构
    	school string //子类的新增属性
    }
    
  • 相关阅读:
    Matlab之快速傅里叶变换
    关于Debug和Release的区别 (VS C#)
    QSqlQuery::value: not positioned on a valid record
    UML系列图--用例图
    SQLite 数据类型总结
    c++构造函数
    求Fibonacci数列通项公式
    ObjectMapper类
    命令行运行jar 提示找不到主程序解决方案
    httpclient框架实现接口自动化的思路(二)
  • 原文地址:https://www.cnblogs.com/yzg-14/p/12247513.html
Copyright © 2011-2022 走看看