Golang派生类型

Golang派生类型

  • (指针类型(Pointer)
  • 数组类型 (Arrayllist)
  • 结构化类型 (Struct)
  • 通道类型 (Channel )
  • 函数类型(Func)
  • 切片类型 (Slice)
  • 接口类型(Interface)
  • Map 类型

指针 Pointer

声明指针

1
var Name *Type

Name :指针名 Type: 指针类型 注意: 指针需要指向的是一个具体的地址

声明地址需要在要声明的变量前面加 &

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main  
  
import "fmt"  
  
func main() {  
   var a int = 10  
  
   fmt.Println(a)  
  
   var b *int  
  
   b = &a //指针b 指向 a 的地址  
  
   *b = 100 //将 b 指向的内存地址赋为 100  
   fmt.Println(a, *b)   //输出 a 和 指针b 指向的值  
   fmt.Println(a == *b) //查看 a 和 *b 指向的值是否相等  
   fmt.Println(&a == b) //查看 a 的地址和 b的指针地址是否相等  
}

输出结果:

1
2
3
4
10
100 100
true
true

图解: https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/Pointer1.png

数组 Arrayllist

数组的声明

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

1
var name [size] type

name : 数组名称

size : 数组长度

type : 数组中数据类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

import "fmt"

func main() {

var Arrayllist  [5] int  //定义长度为 3 ,数据类型为int ,名为 Arrayllist 的数组

for i := 0; i < len(Arrayllist); i++ {  //遍历数组
fmt.Println("Arrayllist[", i, "]: ", Arrayllist[i])  //输出
}

}

输出结果:

GoList1.png

数组初始化

  • 静态初始化:

给出初始化值,由系统决定长度   

1
2
3
var Arrayllist = [...]int8{1, 2, 3, 4, 5,6,7,8,9,10}
//或者
Arrayllist := [...]int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  • 动态初始化:

只指定长度,由系统给出初始化值

1
2
3
var Arrayllist = [5] int8 {1,2,3,4,5}
//或者
Arrayllist := [5] int8 {1,2,3,4,5}

遍历数组

可以使用for循环来遍历数组:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

import "fmt"

func main() {

var Arrayllist  [5] int  //定义长度为 3 ,数据类型为int ,名为 Arrayllist 的数组

for i := 0; i < len(Arrayllist); i++ {  //遍历数组
fmt.Println("Arrayllist[", i, "]: ", Arrayllist[i])  //输出
	}

}

切片 Slice

Go 语言切片(Slice)是对数组的抽象。

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

可以理解为切片是一个有着自动扩容功能的数组。

相关资料:https://blog.go-zh.org/go-slices-usage-and-internals

切片的声明

切片的声明和数组类似,只不过不需要定义长度。

1
var name []type  //声明切片

name : 切片名

type : 切片里的数据类型

因为切片是引用类型,可以使用make函数来声明一个切片。

1
2
3
4
5
6
7
8
9
var name []int = make([]type, len)

//或者

var name = make([]type, len)

//或者

name := make([]type, len)

len : 切片初始长度

也可以指定容量,其中 capacity 为可选参数

1
make([]type, len, capacity)

切片的初始化

直接初始化

1
var Silce = []int{1, 2, 3, 4, 5}

截取数组进行初始化

1
2
3
4
var ArrayList = [5]int{1, 2, 3, 4, 5} //声明数组 ArrayList

// ArrayList[startIndex:endIndex] 
var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个

startIndex : 开始下标(左包含)

endIndex : 结束下标,但不包含结束下标对应的值(右不包含)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import "fmt"

func main() {
var ArrayList = [5]int{1, 2, 3, 4, 5} //声明数组 ArrayList

var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个

fmt.Println(Silce) //输出切片

}

输出结果:

GoSilce1.png

遍历切片

和数组一样,切片也是可以使用for循环遍历的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {
var ArrayList = [5]int{1, 2, 3, 4, 5} //声明数组 ArrayList

var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个

for i := 0; i < len(Silce); i++ {  //遍历切片
fmt.Println(Silce[i])
	}

}

补充

空切片

如果只是单纯的声明一个切片,会导致声明成了一个空(nil)切片,空切片的长度为0,

SilceAppend0-1024x600.png

需要使用append()函数来给空切片添加值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
var Silce_A []int
Silce_A = append(Silce_A, []int{1, 2, 3, 4, 5}...) //使用append为空切片添加元素

if Silce_A == nil { //条件判断

fmt.Println("len(Silce_A) =", len(Silce_A))  //输出切片长度

	} else {

fmt.Println("len(Silce_A) =", len(Silce_A))

	}
}

输出结果:

https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/SilceAppend.png

append函数 和 copy 函数

copy 来拷贝切片

append 函数用来给切片添加新元素

copy函数进行的拷贝是深拷贝的方式,即创建新的内存地址用于存放复制的对象。
两数组相互独立,不受影响

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import "fmt"

func main() {

var Silce = []int{1, 2, 3}

Silce = append(Silce, 4) //append

fmt.Println("Silce =", Silce)

var SilceCopy = make([]int, len(Silce))

copy(SilceCopy, Silce) //copy

if SilceCopy == nil {
fmt.Println("SilceCopy is nil")
	} else {
fmt.Println("SilceCopy = ", SilceCopy)
	}

fmt.Println("-------------------------")

Silce = append(Silce, 5)  //给切片Silce添加元素

fmt.Println("Silce =", Silce) //输出
fmt.Println("SilceCopy = ", SilceCopy)

}

输出结果:

https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/GoSilceCopyAppend1.png

使用append来实现删除切片元素

Go中没有提供专门删除元素的函数,而是通过切片本身的特点来删除元素。

即以被删除元素为分界点,再利用append将前后两个部分的内存重新连接起来。

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c6eb585adf954b948097a9517835eda3~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp

1
name = append(name[:index], name[index+1:]...)

index : 要删除的元素下标

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {

var Silce = []int{1, 2, 3, 4, 5}

        //Silce[:3]只能取到下标为0 1 2 的元素,取不到下标为 3 的元素
        //而Silce[4:]... 能取到包含下标为 4 的元素,实际效果就是下标前移
        //实现删除的效果
Silce = append(Silce[:3], Silce[4:]...)  //删除下标为3的元素

fmt.Println(Silce)

}

len函数和cap函数

切片是可索引的,并且可以由 len() 方法获取长度。

切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {
var ArrayList = [10]int{1, 2, 3, 4, 5, 6, 7, 8} //声明数组ArrayList长度为10

var Silce []int = ArrayList[0:4] //声明Silce,Silce的值是截取数组,第一个到第四个

fmt.Println("len(Silce) = ", len(Silce))  //获取长度

fmt.Println("cap(Silce) = ", cap(Silce))  //切片最长可以达到多少

}

输出结果:

https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/GoSilceCapLen1.png

可见如果是截取数组的切片,长度和截取的原数组长度有关。

如果是声明并且初始化的数组,最大长度是初始长度,而使用append函数添加后,最大长度会自动变化。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {

var Silce = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

fmt.Println("len(Silce) = ", len(Silce)) //声明并初始化的切片长度

fmt.Println("cap(Silce) = ", cap(Silce)) //声明并初始化的切片最大长度

Silce = append(Silce, []int{11, 12, 13, 14, 15}...)

fmt.Println("len(Silce)Append = ", len(Silce)) //使用Append添加一次后的切片长度

fmt.Println("cap(Silce)Append = ", cap(Silce)) //使用Append添加一次后的切片最大长度

Silce = append(Silce, []int{16, 17, 18, 19, 20, 21}...)

fmt.Println("len(Silce)Append2 = ", len(Silce)) //使用Append添加第二次次后的切片长度

fmt.Println("cap(Silce)Append2 = ", cap(Silce)) //使用Append添加第二次后的切片最大长度

}

输出结果:

https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/GoSilceCapLen2.png

MAP

Go语言中的map是一个无序的key : vlaue 键值对的数据结构容器,map内部实现是哈希表hash。

map的特点就是类似与Python的字典,,按照key来找到对应的value 。key指向数据的值。

Map的声明

Go语言的map同样是可是使用make来声明的。

1
2
3
4
5
6
7
8
9
var Name [KeyType]ValueType  //声明map, 此时声明的map是nil map,不存在初始值

//或者

var Name = make(map[KeyType]ValueType)

//或者

var Name = map[KeyType]ValueType{key:value,key:value}  //这种要静态初始化

Name : 变量名

KeyType :Key的数据类型

ValueType : Value的数据类型

Map的初始化

map的初始化和数组类似。

但是要直接var Name [KeyType]ValueType 来声明map会得到一个空(nil map)无法被赋值。

https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/GoMap1.png

就需要make函数来创建一个非空的map。这样才可以赋值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package main

import "fmt"

func main() {
var Map map[int]int

Map = make(map[int]int) //make函数来创建一个非空的map,赋值。

for i := 0; i < 5; i++ {
Map[i] = i
}
fmt.Println("Map: ", Map)

}

输出结果:

https://xenolies-blog-images.oss-cn-hangzhou.aliyuncs.com/Pics/GoMap2.png

当然也可以利用这个来做个判断:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {

var Map = make(map[int]int)

for i := 0; i < 5; i++ {
Map[i] = i
}

Value, err := Map[5]
if err == true { //如果能取到kKey为5的值,err为true,否则为false
fmt.Println("Value: ", Value)
} else {
fmt.Println("不存在该键")
}

fmt.Println("Map: ", Map)

}

遍历Map

可以使用 for range 来遍历map

  • 遍历Key
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

func main() {

var Map = make(map[string]int)

Map["一"] = 1
Map["二"] = 2
Map["三"] = 3
Map["四"] = 4
Map["五"] = 5

for key := range Map {
  // 使用for range 遍历key
fmt.Println(key)
}

}

输出结果:

由于内部实现是哈希值的原因,map不像切片或者数组有序,不存在下标。

GoMapRange1.png

  • 遍历Value
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main() {

var Map = make(map[string]int)

Map["一"] = 1
Map["二"] = 2
Map["三"] = 3
Map["四"] = 4
Map["五"] = 5

for _, value := range Map {  //稍微修改以下即可,key直接用匿名变量
fmt.Println(value)
}

}

输出结果:

GoMapRange2.png

  • 遍历Key,Value
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main() {

var Map = make(map[string]int)

Map["一"] = 1
Map["二"] = 2
Map["三"] = 3
Map["四"] = 4
Map["五"] = 5

for key, value := range Map {
fmt.Println(key, ": ", value)
}

}

输出结果:

GoMapRange3.png

删除元素

elete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

func main() {

var Map = make(map[int]int)
for i := 0; i < 5; i++ {
Map[i] = i
}

delete(Map, 0) //删除key 为 0的元素
delete(Map, 1)//删除key 为 1的元素
delete(Map, 2)//删除key 为 2的元素

for key, value := range Map {
fmt.Println(key, ": ", value)  //遍历输出
}

}

输出结果:

GoMapRange4.png

其他

不知道是不是个例,我如果把map类型改为 [int]int , 然后遍历key或者value会报错。报错原因是因为window安全中心检测到了病毒。这时候要把实时检测关掉来运行程序,或者卸载Goland重装一遍。

结构体 Struct

golang有个非常重要的关键字 struct ,也是golang的一个特色.

结构体特点

结构体是一个可以存储不同数据类型的数据类型, 声明完后,它可以和数据类型一样,也有指针值等等.

定义结构体

1
2
3
4
5
6
type Person struct {  //Person结构体
   Age  int    //参数
   Name string  
   Job  string  
   Sex  bool  
}

声明结构体

结构体可以作为变量声明使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main  
  
import "fmt"  
  
type Person struct {  
   Age  int  
   Name string  
   Job  string  
   Sex  bool  
}  
  
func main() {  
   var person Person //创建Person对象  
   person.Age = 20   //各参数赋值  
   person.Name = "LiMing"  
   person.Job = "Student"  
   person.Sex = true  
  
   fmt.Println(person)  //输出变量  
  
}

输出结果:

1
{20 LiMing Student true}

当然结构体也是可以隐式声明的,类似JAVA语言的实例化

隐式声明有两种方式

1
2
3
4
5
6
person2 := Person{ //隐式声明  
   Age:  40,  
   Name: "Danny",  
   Job:  "Worker",  
   Sex:  false,  
}
1
person3 := Person{50, "Jenny", "Teacher", true} //隐式声明

注意第二个种声明必须按照顺序给定参数.

完整代码 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main  
  
import "fmt"  
  
type Person struct {  
   Age  int  
   Name string  
   Job  string  
   Sex  bool  
}  
  
func main() {  
   var person Person //创建Person对象  
   person.Age = 20   //各参数赋值  
   person.Name = "LiMing"  
   person.Job = "Student"  
   person.Sex = true  
  
   fmt.Printf("person: %v\n", person) //输出变量  
  
   person2 := Person{ //隐式声明  
      Age:  40,  
      Name: "Danny",  
      Job:  "Worker",  
      Sex:  false,  
   }  
  
   fmt.Printf("person2: %v\n", person2)  
  
   person3 := Person{50, "Jenny", "Teacher", true} //隐式声明2  
  
   fmt.Printf("person3: %v\n", person3)  
  
}

输出结果:

1
2
3
person: {20 LiMing Student true}
person2: {40 Danny Worker false}
person3: {50 Jenny Teacher true}

默认声明会给定初始值

1
2
3
4
5
6
def := Person{  
   Age:  0,  
   Name: "",  
   Job:  "",  
   Sex:  false,  
}

以及一种特殊的声明方法:

1
nul := new(Person) 
1
nul: &{0   false}

不过这个出来的直接就是带有地址的.

访问结构体

由于 struct 是一种特殊的数据类型,他也可以当做一个数据类型用在函数中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main  
  
import "fmt"  
  
type Person struct {  
   Age  int  
   Name string  
   Job  string  
   Sex  bool  
}  
  
func main() {  
  
   person2 := Person{ //隐式声明  
      Age:  40,  
      Name: "Danny",  
      Job:  "Worker",  
      Sex:  false,  
   }  
  
   Test(person2)  
}  
  
func Test(person Person) {  
   fmt.Println(person.Name)  
}

输出结果:

1
Danny

接口 Interface

接口的定义: 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。

接口的使用

声明接口

1
2
3
4
5

type Person interface { //声明接口  
   Say()   //定义方法
   Listen()  
}

实现接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
type Person interface { //声明接口  
   Say()  
   Listen()  
}  
  
type person1 struct {   //声明新结构体
   Name string  
   Age  int  
}  
  
func (p person1) Say() { //实现接口Say
   fmt.Println(p.Name, "说了一句话")  
}  
  
func (p person1) Listen() {  //实现接口Listen
   fmt.Println(p.Name, "在听")  
}

简单使用

通过接口实现实例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main  
  
import "fmt"  
  
type Person interface { //声明接口  
   Say()  
   Listen()  
}  
  
type person1 struct {  
   Name string  
   Age  int  
}  
  
func (p person1) Say() { //实现接口  
   fmt.Println(p.Name, "说了一句话")  
}  
  
func (p person1) Listen() {  
   fmt.Println(p.Name, "在听")  
}  
  
func main() {  
   var P Person  //接口类型
  
   p2 := person1{  //实例
      Name: "person2",  
      Age:  10,  
   }  
  
   P = p2  
  
   P.Say()  //通过接口实现实例内部的函数
   P.Listen()  
  
}

输出结果:

1
2
person2 说了一句话
person2 在听

注意的是,只要实现了接口的结构体,均可使用此方法来调用实例的函数,但是通过接口的话无法调用到结构体的内容.

通过接口实现泛型效果

1
2
3
func Fun(inf interface{}) { //定义函数,将类型设为空接口,即可实现  
  
}

在方法中使用接口

这样的话,只用将符合接口的实例传入即可调用接口的方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

package main  
  
import "fmt"  
  
type Person interface { //声明接口  
   Say()  
   Listen()  
}  
  
type person1 struct {  
   Name string  
   Age  int  
}  
  
func (p person1) Say() { //实现接口  
   fmt.Println(p.Name, "说了一句话")  
}  
  
func (p person1) Listen() {  
   fmt.Println(p.Name, "在听")  
}  
  
func main() {  
   var P Person  
  
   p2 := person1{  
      Name: "person2",  
      Age:  10,  
   }  
  
   P = p2  
  
   P.Say()  
   P.Listen()  
  
   p3 := person1{  
      Name: "person3",  
      Age:  11,  
   }  
  
   Fun(p3)  
  
}  
  
func Fun(per Person) { //定义函数,将类型设为空接口,即可实现  
   per.Say()  
   per.Listen()  
}

输出结果:

1
2
3
4
person2 说了一句话
person2 在听
person3 说了一句话
person3 在听

其他

Go语言接口 和 JAVA接口 的区别 java 实现结果需要implement 关键词来指定实现具体接口, 而golang的话只需要与某个接口中的某个方法名字相同即可,golang更加松散.

通道 Channel

Channel的主要使用是在Golang 的并发中: 相关笔记:Golang并发编程

函数 Func

何为函数

函数是基本的代码块,用于执行一个任务。

Go 语言最少有个 main() 函数。

你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。

函数声明告诉了编译器函数的名称,返回类型,和参数。

函数的定义和调用

函数定义

Go语言定义函数的语法:

1
2
3
4
5
func function_name( [parameter list] ) [return_types] {
   函数体

   [return return_Numbers]
}

func :定义函数的关键字

function_name : 函数名

parameter list : 参数列表,需要传入的参数和参数类型,根据需要选择可以不设置。

return_types : 返回值类型,返回一系列的值,根据需要选择可以不设置。

函数体:函数定义的代码集合。

1
2
3
4
5
6
func PrintHello() { //打印Hello的函数

var String = "Hello"
fmt.Println(String)

}
函数调用

当创建函数时,你定义了函数需要做什么,通过调用该函数来执行指定任务。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "fmt"

func main() {
PrintHello()  //调用PrintHello函数

fmt.Println(PrintHelloWorld()) //调用PrintHelloWorld函数


        fmt.Println(Add(10, 10))  //调用求和函数
}

func PrintHello() { //PrinrHello函数,无参,无返回值

var String = "Hello"
fmt.Println(String)


}

func PrintHelloWorld() string { //PrintHelloWorld函数,无参,有返回值

var String = "Hello,World!"
return String

}

func Add(X int, Y int) int {  //求和函数,有参,有返回值
Res := X + Y
return Res
}

运行结果:

Gofunction1.png

函数类型

使用Type关键字可以定义函数类型。

在Go语言中,type可以定义任何自定义的类型。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import "fmt"

func main() {
type T1 func(int, int) int  //使用type关键字,定义T1类型
var F T1 = Add  //声明T1类型的变量F ,将Add函数赋给F
f1 := F(1, 4)
fmt.Println(f1)

var F2 T1 = subtract
f2 := F2(10, 40)
fmt.Println(f2)

fmt.Println(f1 + f2)

}

func Add(X int, Y int) int {  //Add函数
Res := X + Y
return Res
}

func subtract(X int, Y int) int {  //subtract函数
Res := X - Y
return Res
}

输出结果:

Gofunction2.png

高阶函数

函数作为参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
PrintHello("Sam", SayHello)

}

func SayHello(name string) string {
var Hello string = name + " Hello"
fmt.Println("func SayHello: ", Hello)
return Hello
}

func PrintHello(name string, f func(string2 string) string) {
fmt.Println("func PrintHello: ", name, f(name))
}

输出结果:

Gofunction3.png

函数作为返回值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"strconv"
)

func main() {
fmt.Println(Add(10, 20))

}

func Add(x int, y int) string {
var Res = x + y
return ToString(Res)
}

func ToString(z int) string {
var Res = strconv.Itoa(z)  //使用 strconv.Itoa()将整型数字转为字符串数字
return Res
}

匿名函数

Go语言中的函数无法实现函数的嵌套,但是可以通过匿名函数来实现相似的效果。

匿名函数效果类似Python中的lamda

格式:

1
2
3
func(参数列表) 返回值 { 
    函数体
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import "fmt"

func main() {
Add := func(X int, Y int) int { //匿名函数
return X + Y
}

A := Add(1, 2) //调用匿名函数
fmt.Println("var A =", A) //输出
}

输出结果:

var A = 3

其他

strconv.Itoa() 和 string()的区别

string()是直接整数类型的数字转为ASCII码值等于该整形数字的字符。

而strconv.Itoa() 是转换成对应的字符串类型的数字。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"fmt"
"strconv"
)

func main() {

var Number = 40

fmt.Println(Number)
fmt.Printf("%T\n", Number)
fmt.Println("------------------")

fmt.Println(string(Number))
fmt.Printf("%T\n", string(Number))

fmt.Println("------------------")

fmt.Println(strconv.Itoa(Number))
fmt.Printf("%T\n", strconv.Itoa(Number))

}

输出结果:

Gofunction4.png

0%