Go(2)

目录

 

Go 语言函数

函数参数

函数用法

Go 语言变量作用域

局部变量

全局变量

形式参数

Go 语言数组

初始化数组

 

Go 语言结构体

定义结构体

Go 语言切片(Slice)

切片初始化

len() 和 cap()

Go 语言Map(集合)

delete()

 

Go 语言接口

Go 并发

通道(channel)


Go 语言函数

函数参数

函数如果使用参数,该变量可称为函数的形参。

形参就像定义在函数体内的局部变量。

调用函数,可以通过两种方式来传递参数:

传递类型

描述

值传递

值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数。

 

函数用法

函数用法

描述

函数作为另外一个函数的实参

函数定义后可作为另外一个函数的实参数传入

闭包

闭包是匿名函数,可在动态编程中使用

方法

方法就是一个包含了接受者的函数

 

Go 语言变量作用域

局部变量

在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。

以下实例中 main() 函数使用了局部变量 a, b, c:

func localVariable() {
	/* 声明局部变量 */
	var a, b, c int

	/* 初始化参数 */
	a = 10
	b = 20
	c = a + b

	fmt.Printf("结果 a = %d, b = %d, c = %d", a, b, c)
}

全局变量

在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。

全局变量可以在任何函数中使用,以下实例演示了如何使用全局变量:

var g int

func globalVariable() {
	/* 声明局部变量 */
	var a, b int

	/* 初始化参数 */
	a = 10
	b = 10
	g = a + b

	fmt.Printf("a = %d, b = %d, g = %d", a, b, g)

}

形式参数

形式参数会作为函数的局部变量来使用。实例如下:

/* 声明全局变量 */
var a int = 10

func formalParameters() {
	/* 声明局部变量 */
	var a int = 10
	var b int = 10
	var c int = 0

	fmt.Printf("main 中 a = %d,b = %d, c = %d\n", a, b, c)
	c = sum(a, b)
	fmt.Printf("main 中 a = %d,b = %d, c = %d\n", a, b, c)
}

/* 函数定义-两数相加 */
func sum(a, b int) int {
	fmt.Printf("sum 函数中 a = %d\n", a)
	fmt.Printf("sum 函数中 b = %d\n", b)

	return a + b
}

Go 语言数组

Go 语言提供了数组类型的数据结构。

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。

相对于去声明 number0, number1, ..., number99 的变量,使用数组形式 numbers[0], numbers[1] ..., numbers[99] 更加方便且易于扩展。

数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。

初始化数组

func array() {
	var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
	//balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

	var balance2 = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
	// balance2 := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

	fmt.Printf("balance %v", balance)
	fmt.Printf("balance2 %v", balance2)
}

 

Go 语言结构体

Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

定义结构体

结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:

type struct_variable_type struct{
    member definition
    member definition
    ...
    member definition
}
type Books struct {
	title   string
	author  string
	subject string
	book_id int
}

func structuralMorphology() {
	//创建一个新的结构体
	fmt.Println(Books{"Go", "Go", "Go", 1})

	//key => value 格式
	fmt.Println(Books{title: "go", author: "go", subject: "go", book_id: 2})

	//忽略的字段为0或空
	fmt.Println(Books{title: "1", book_id: 3})
}

 

Go 语言切片(Slice)

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

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

切片初始化

s := [] int {1, 2, 3}

直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3

s := arr[:]

初始化切片 s,是数组 arr 的引用。

s := arr[startIndex : endIndex]

将 arr 中从下标 startIndex 到 endIndex -1 下的元素创建为一个新的切片。

s := arr[startIndex :]

默认 endIndex 时将表示一直到arr的最后一个元素。

s := arr[: endIndex]

默认 startIndex 时将表示从 arr 的第一个元素开始。

s1 := s[startIndex : endIndex]

通过切片 s 初始化切片 s1。

s := make([]int, len, cap)

len() 和 cap()

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

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

func printSlice(x []int) {
	fmt.Printf("len = %d cap = %d slice = %v \n", len(x), cap(x), x)
}

printSlice(make([]int, 3, 5))

//len = 3 cap = 5 slice = [0 0 0]

 

Go 语言Map(集合)

Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。

Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。

func fMap() {
	/* 创建集合 */
	var countryCapitalMap map[string]string
	countryCapitalMap = make(map[string]string)

	/* map 插入key - value, 各个国家对应的首都*/
	countryCapitalMap["China"] = "beijing"
	countryCapitalMap["France"] = "bali"
	countryCapitalMap["Italy"] = "luoma"
	countryCapitalMap["Japan"] = "dongjing"
	countryCapitalMap["India"] = "xindeli"

	/* 使用键输出地图值 */
	for country := range countryCapitalMap {
		fmt.Println(country, "首都是", countryCapitalMap[country])
	}

	/* 查看元素集合是否存在 */
	capital, ok := countryCapitalMap["America"]

	fmt.Println(capital)
	fmt.Println(ok)

	if ok {
		fmt.Println("America的首都是", capital)
	} else {
		fmt.Println("America的首都不存在")
	}

}

delete()

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

func deleteMap() {
	/* 创建map */
	countryCapitalMap := map[string]string{"China": "beijing", "Japan": "riben", "France": "bali"}
	fmt.Println("原始地图")

	/* 打印地图 */
	for country := range countryCapitalMap {
		fmt.Println(country, "首都是", countryCapitalMap[country])
	}

	/* 删除元素 */
	delete(countryCapitalMap, "France")

	fmt.Println("法国条目被删除")
	fmt.Println("删除元素后的地图")

	/* 打印地图 */
	for country := range countryCapitalMap {
		fmt.Println(country, "首都是", countryCapitalMap[country])
	}

}

 

Go 语言接口

Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

package main

import (
	"fmt"
)

type Phone interface {
	call()
}

type NokiaPhone struct {
}

func (nokiaPhone NokiaPhone) call() {
	fmt.Println("I am Nokia, I can call you!")
}

type IPhone struct {
}

func (iPhone IPhone) call() {
	fmt.Println("I am iphone, I can call you!")
}

func main() {
	var phone Phone

	phone = new(NokiaPhone)
	phone.call()

	phone = new(IPhone)
	phone.call()
}

 

Go 并发

Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。

goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。

goroutine 语法格式:

go 函数名(参数列表)

例如:

go f(x, y, z)

开启一个新的gorountine:

f(x, y, z)

Go 允许使用 go 语句开启一个新的运行期线程, 即 goroutine,以一个不同的、新创建的 goroutine 来执行一个函数。 同一个程序中的所有 goroutine 共享同一个地址空间。

package main

import (
	"fmt"
	"time"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func main() {
	go say("world")
	say("hello")
}

 

通道(channel)

通道(channel)是用来传递数据的一个数据结构。

通道可用于两个goroutine之间传递一个指定类型的值来同步运行和通讯。操作符   <-  用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

ch <- v //把 v 发送到通道 ch
v := <-ch // 从 ch 接收数据, 并把值赋给 v

声明一个通道很简单。使用 chan 关键字即可,通道在使用前必须先创建,

ch := make(chan int)
func passageway() {
	s := []int{7, 2, 8, -9, 4, 0}

	c := make(chan int)

	go sums(s[:len(s)/2], c)
	go sums(s[len(s)/2:], c)

	x, y := <-c, <-c //从通道c中接收

	fmt.Println(x, y, x+y)
}

func sums(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}

	c <- sum //把 sum 发送到通道 c
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值