golang面向对象之结构体上

1、快速入门–以面向对象方式解决养猫问题(struct)

package main

import "fmt"

//定义一个Cat结构体,将Cat的各个字段/属性信息放入带Cat结构体进行管理
type Cat struct {
	Name string
	Age int
	Color string
	Hobby string
}
func main() {
	//创建一个Cat变量
	var cat1 Cat
	cat1.Name="tom"
	cat1.Age=10
	cat1.Color="灰色"
	cat1.Hobby="吃"
	fmt.Println("cat1=",cat1)

	fmt.Println("猫的信息如下:")
	fmt.Println("name=",cat1.Name)
	fmt.Println("Age=",cat1.Age)
	fmt.Println("color=",cat1.Color)
	fmt.Println("hobby=",cat1.Hobby)
}

2、结构体和结构体变量(实例)的区别和联系

通过上面的案例我们可以看出:
(1)结构体是自定义的数据类型,代表一类事物.
(2)结构体变量(实例)是具体的,实际的,代表一个具体变量

3、如何声明一个结构体

基本语法

type 结构体名称 struct{
	field1 type
	field2 type
}

举例

type Student struct {
	Name string //字段
	Age int
	Score float32
}

字段注意事项和细节说明

(1)字段声明语法同变量,示例:字段名 字段类型
(2)字段的类型可以为:基本类型、数组或引用类型
(3)在创建一个结构体变量后,如果没有给字段赋值,都对应一个零值(默认值),规则同 前面讲的一样。
布尔类型是false,数值是0,字符串是"。 数组类型的默认值和它的元素类型相关,比如score [3]int则为[0, 0, 0] 指针,slice, 和map的零值都是nil ,即还没有分配空间。

案例演示

package main

import "fmt"

//定义一个Cat结构体,将Cat的各个字段/属性信息放入带Cat结构体进行管理
type Cat struct {
	Name   string
	Age    int
	Scores [5]float64
	ptr    *int              //指针
	slice  []int             //切片
	map1   map[string]string //map
}

func main() {
	//创建一个Cat变量
	var cat1 Cat
	
	fmt.Println("cat1=", cat1)
	if cat1.ptr == nil {
		fmt.Println("ok1")
	}
	if cat1.slice == nil {
		fmt.Println("ok2")
	}
	if cat1.map1 == nil {
		fmt.Println("ok3")
	}
	//使用slice时一定要make
	cat1.slice = make([]int, 10)
	cat1.slice[0] = 100 //ok

	//使用map时要先make
	cat1.map1 = make(map[string]string)
	cat1.map1["key1"] = "tom1"
	fmt.Println(cat1)
}

运行结果
在这里插入图片描述

(4)不同结构体变量的字段是独立,互不影响,一个结构体变量字段的更改,不影响另外一个结构体,结构体是值类型。

案例演示

type Monster struct {
	Name string
	Age  int
}
func main() {
	var monster1 Monster
	monster1.Name = "牛魔王"
	monster1.Age = 100

	monster2 := monster1 //结构体是值类型,默认为值拷贝
	monster2.Name = "青牛精"
	fmt.Println("monster1=", monster1) //monster1= {牛魔王 100}
	fmt.Println("monster2=", monster2) //monster2= {青牛精 100}
}

4、创建结构体变量和访问结构体字段

方式1——直接声明

var person Person

方式2——{}

type Person struct {
	Name string
	Age  int
}
var person Person = Person{}
//p2.Name = "tom"
//p2.Age = 20
p2 := Person{"mary",20}

方式3——&
var person *Person = new(Person)

type Person struct {
	Name string
	Age  int
}
func main() {
	var p3 *Person = new(Person)
	//因为p3是一个指针,因此标准的给字段赋值方式
	// (*p3).Name="smith",也可以这样写p3.Name="smith"
	//当对p3.Name="smith"进行赋值时,golang的底层会给p3加上取值运算(*p3).Name="smith"
	(*p3).Name = "smith"
	//p3.Name = "join"
	
	(*p3).Age = 10
	//p3.Age = 100
	fmt.Println(p3)
}

方式4——{}
var person *Person = &Person{}

type Person struct {
	Name string
	Age  int
}
func main() {
	//var person *Person  = &Person{"mary",10}
	var person *Person  = &Person{}
	//因为person 是一个指针,因此标准的给字段赋值方式
	// (*person).Name="smith",也可以这样写person .Name="smith"
	//当对person .Name="smith"进行赋值时,golang的底层会给person 加上取值运算(*person ).Name="smith"
	//下面的语句一可以直接给字段赋值
	
	(*person).Name = "smith1"
	//person.Name = "join1"

	(*person).Age = 101
	//person.Age = 100
	fmt.Println(person)
}

说明:

(1)第3种和第4种方式返回的是结构体指针。
(2)结构体指针访问字段的标准方式应该是:(*结构体指针).字段名,比如(*person).Name = “tom”
(3)但go做了一个简化,也支持结构体指针字段名, 比如person.Name = “tom”.更加符合程序员使用的习惯,go编译器底层对person.Name做了转化(*person).Name。

5、方法

  在某些情况下,我们要需要声明(定义)方法。比如Person结构体:除了有一些字段外(年龄,姓名…),Person结构体还有一些行为,比如:可以说话、跑步…通过学习,还可以做算术题。这时就要用方法才能完成。
  Golang中的方法是作用在指定的数据类型.上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct.
(1)方法的声明和调用

type A struct {
 Num int
}
func (a A) test() {
 fimt.Println(a.Num)
}

➢对上面的语法的说明

  1. func(a A) test() {} 表示A结构体有一方法,方法名为test
  2. (a A) 体现test 方法是和A类型绑定的

案例演示

type Person struct {
	Name string
	Age  int
}

//给Person绑定一个方法
func (p Person) test() {
	fmt.Println("test() name=", p.Name)
}
func main() {
	var p Person
	p.Name = "tom"
	p.test() //调用方法
}

➢对上面的总结

  1. test 方法和Person类型绑定
    2)test方法只能通过Person类型的变量来调用,而不能直接调用,也不能使用其它类型变量来调用

方法快速入门
(1)给Person结构体添加sum1方法,可以计算从1+…+1000 的结果,说明方法体内可以函数一样,进行各种运算

func (p Person) sum1()  {
	res := 0
	for i:=1;i<1000;i++ {
		res+=i
	}
	fmt.Println(p.Name,"计算的结果为=",res)
}

(2)给Person结构添加sum2方法,该方法可以接收一个数n,计算从1+…+n的结果

func (p Person) sum2(n int)  {
	res := 0
	for i:=1;i<n;i++ {
		res+=i
	}
	fmt.Println(p.Name,"计算的结果为=",res)
}
func main() {
	var p Person
	p.sum1()
	p.sum2(100)
}

(3)给Person结构体添加getSum方法,可以计算两个数的和,并返回结果

func (p Person) getSum(n1 int, n2 int) int {
	return n1 + n2
}
func main() {
	var p Person
	res:=p.getSum(10,20)
	fmt.Println(res)
}

案例1

请编写-一个程序,要求如下:
1)声明一个结构体Circle, 字段为radius
2)声明一个方法area和Circle绑定,可以返回面积。

type Circle struct {
	radius float64
}

func (c Circle) area() float64 {
	return 3.14 * c.radius * c.radius
}
func main() {
	var c Circle
	c.radius = 5.0
	area := c.area()
	fmt.Println("面积为=", area)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值