栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

go语言从入门到进阶实战(go入门教程)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

go语言从入门到进阶实战(go入门教程)

指针

之前学的是java,现在学go,突然给我整个指针给我整的有点不太适应
经过过一段时间学习,发现指针并没有那么难

首先说一下,什么是指针?
指针变量,就是一个存放地址的变量。
何谓地址?地址就是一个变量它在内存中所在的位置

func main() {
	a := 10
	
	// 这里的 b 就是指针变量	
	b := &a // “&” 是取地址的意思,这里就是把a变量值的地址拿出来,给变量b
	
	fmt.Println(&a) // 0xc000018098
	fmt.Println(&b) // 0xc000006028 变量都有地址,指针变量作为一个变量,当然也有自己的地址咯
	fmt.Println(b) // 0xc000018098
	fmt.Println(*b) // 10
	// “*”是取地址对应的变量值

	a = 11
	fmt.Println(*b) //11
}

指针类型

除了上篇说的那么多类型之外,还有一种类型叫做指针类型
上面不是说过指针是什么东西了吗?这里为什么还要再说呢?

虽然说指针变量存的是地址,但也不能随便往里面放地址。只能放指针类型对应变量的地址
Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等。
现在看这样一个例子

	a := 11 // a是int型
	c := "RZZY" // c 是string型
	d := &a // d 以这种方式存放a地址,d现在就是 *int 型
	
	// 现在我想让d改存string型变量的地址,做不到了!
	d = &c // 无法将 '&c' (类型 *string) 用作类型 *int
结构体

结构体,它就像一个箱子,里面放着各种东西
Go语言中是通过结构体来实现面向对象的

type Person struct{
	name, gender string
	age int
}

这么一个结构体,描述的就是一个 人

而结构体里的字段,不就是属性么!

像不像“类”?

“类”有了,我们就该实例化了
var 结构体实例 结构体类型

var p1 Person
p1.name = "RZZY"
p1.gender = "Man"
p1.age = 180

这样一个实例就有了,但现在和java类的实例化还是有点不太一样,因为java的对象是引用类型的,而我们现在实例化出来的结构体,直接打印一下,发现不太对,这结构体怎么和java的对象不一样,打印出来的不是地址?

加上go语言参数传递是值传递,如果我们把这个“对象”传递给函数,函数会复制一个这个"对象"的副本,之后所有的修改都不会影响到原来的这个"对象"

type Person struct {
	Name, Gender string
	Age          int
}

func main() {
	var p1 Person
	p1.Name = "RZZY"
	p1.Gender = "Man"
	p1.Age = 180
	fmt.Println(p1) // {RZZY Man 180}
	modifyP(p1)
	fmt.Println(p1) // {RZZY Man 180} 完全没有变化
}

func modifyP(p Person) {
	p.Name = "RZXY"
}

有问题就有解决方法,我们能想到的就是,直接传递指针类型不就好了!
指针类型变量的值就是地址,修改的时候是根据指定地址的值进行修改,这样就能做到修改原"对象"

func main() {
	var p1 Person
	p1.Name = "RZZY"
	p1.Gender = "Man"
	p1.Age = 20
	fmt.Println(p1) // {RZZY Man 180}
	modifyP(&p1) // 这里的参数将原来的(p1)改成了(&p)
	fmt.Println(p1) // {RZXY Man 180} 修改成功!
}

func modifyP(p *Person) { // 这里的参数将原来的(p Person)改成了(p *Person)
	p.Name = "RZXY"
}

好了,接下来就是下一个东西,结构体的指针类型!

创建指针类型的结构体

通过使用new()来对结构体进行实例化,结构体对象会被分配内存,而得到的就只是“对象”的地址

var p2 = new(Person)
fmt.Println(p2) // &{  0}  字段默认是对应类型的零值

我们注意到,前面多了个"&",也就是取地址符号!

这样我们在传递参数的时候,可以直接传递这个指针类型的结构体

结构体字段的可见性!

结构体中字段大写开头表示可公开访问,小写表示私有(仅在定义当前结构体的包中可访问)

函数与结构体

既然属性有了,方法也该有,但是在方法之前要先了解一下Go里的函数

函数
func 函数名(参数列表) (返回值列表){
	函数体...
}

func Hello(a, p string) { // 类型相同的两个参数可以只写一次类型
	fmt.Printf("%s岁的%s向你问好!n", p, a)
}
func Calc(c, d int) (sum, avg int) {
	// return c + d, sum / 2   可以直接这样一句话,也可以向下面那样省略掉return后面的地方
	sum = c + d
	avg = sum / 2
	return
}
func main() {
	n := "Hikari"
	a := "18"
	Hello(n, a) // 18岁的Hikari向你问好!

	fmt.Println(Calc(4, 8)) // 12 6
}

通过上面的例子我们可以发现,Go的函数有这样几个特点:

    多个连续的参数类型相同时,可以只写一次类型返回值可以有多个给返回值命名后,return 后面不用再写东西

除此之外,还有如下特性

    函数的参数可以不是固定的,但后面的类型是固定的
func myfunc(args ...int) {    //0个或多个参数
}

func add(a int, args…int) int {    //1个或多个参数
}

func add(a int, b int, args…int) int {    //2个或多个参数
}
// 其中arg是一个slice,可以通过arg[index]依次访问所有参数

函数有多个返回值,那我调用函数只需要其中一个返回值怎么办?
_可以帮你解决这个问题,_能帮你忽略掉对应位置的返回值

还是看上面的那个Calc()函数

sum, _ := Calc(4,6)
_, avg := Calc(4,6)

fmt.Println(sum) // 10
fmt.Println(avg) // 5
方法
// 方法
func (接收者变量 接收者类型) 方法名(参数列表)(返回参数){
	函数体
}

// 函数
func 方法名(参数列表) (返回参数){
	函数体
}

和函数对比一下,我们会发现,方法也就是在函数方法名前面加了个接收者
这个所谓接收者,可以理解成,只有指定的接收者类型才能调用这个方法

type Luna struct {
	level           int
	have, awakening bool
}
type Eto struct {
	level           int
	have, awakening bool
}

var e1 *Eto = &Eto{}

func main() {
	l1 := &Luna{20, true, false}
	l1.Can(true)
	fmt.Println(e1.have)
	// e1.Can()  这里会报错,未解析的引用 'Can'
}

func (l *Luna) Can(fc bool) { // 限制只有Luna的指针类型可以调用
	fmt.Println("If you can !")
	if !fc {
		fmt.Println("No I can't...TAT")
	} else {
		fmt.Println("Character Unlocked!")
		e1.have = true
		e1.level = 1
	}
}

// 运行结果
// If you can !
// Character Unlocked!
// true

就是这样,方法都在结构体外面,方法就像是限制了调用者的函数

方法有了,但总感觉还少了点啥,,,奥对,构造方法!

构造方法

就拿爱托来做实验!

type Eto struct {
	level           int
	have, awakening bool
}
func newEto(level int, have, awakening bool) *Eto {
    return &Eto{
       	level: level,
		have: have ,
		awakening: awakening,
    }
}

仔细观察会发现,这不就是一个函数,返回值是结构体的指针类型吗!
不过限制了我们必须初始化字段值罢了!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/773565.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号