Go语言学习之路
Posted 果子哥丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言学习之路相关的知识,希望对你有一定的参考价值。
Go语言学习之路
Go语言简介
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。
Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。
对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。
第一个Go程序:
go安装地址:https://golang.google.cn/dl/
接下来我们来编写第一个 Go 程序 hello.go(Go 语言源文件的扩展是 .go),代码如下:
hello.go文件
package main
import "fmt"
func main()
fmt.Println("Hello, World!")
要执行 Go 语言代码可以使用 go run 命令。
$ go run hello.go
Hello, World!
此外我们还可以使用 go build 命令来生成二进制文件:
$ go build hello.go
$ ls
hello hello.go
$ ./hello
Hello, World!
Go语言结构
Go 语言的基础组成有以下几个部分:
- 包声明
- 引入包
- 函数
- 变量
- 语句 & 表达式
- 注释
package main // 包声明
import "fmt" // 引用包
func main() // 函数必须包含。 需要注意的是 不能单独放在一行
/* 这是我的第一个简单的程序 */
fmt.Println("Hello, World!")
- 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);
- 当标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
文件结构:
Test
--helloworld.go
myMath
--myMath1.go
--myMath2.go
// helloworld.go
package main
import (
"fmt"
"./myMath"
)
func main()
fmt.Println("Hello World!")
fmt.Println(mathClass.Add(1,1))
fmt.Println(mathClass.Sub(1,1))
// myMath1.go
package mathClass
func Add(x,y int) int
return x + y
// myMath2.go
package mathClass
func Sub(x,y int) int
return x - y
格式化字符串:
fmt.Sprintf 格式化字符串并赋值给新串:
package main
import (
"fmt"
)
func main()
// %d 表示整型数字,%s 表示字符串
var stockcode=123
var enddate="2020-12-31"
var url="Code=%d&endDate=%s"
var target_url=fmt.Sprintf(url,stockcode,enddate)
fmt.Println(target_url)
Go语言变量
声明变量的一般形式是使用 var 关键字:
var identifier type
可以一次声明多个变量:
var identifier1, identifier2 type
intVal := 1 相等于:
var intVal int
intVal =1
package main
import "fmt"
func main()
var a string = "Runoob" // a1 := "Ruoob"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
- 如果你在定义变量 a 之前使用它,则会得到编译错误 undefined: a。
- 如果你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误,a declared but not used。
- 在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。但是全局变量是允许声明后不使用的。
Go语言常量
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。
- 显式类型定义: const b string = “abc”
- 隐式类型定义: const b = “abc”
Go语言运算符
/* & 和 * 运算符实例 */
ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */
fmt.Printf("a 的值为 %d\\n", a);
fmt.Printf("*ptr 为 %d\\n", *ptr);
Go语言循环语句
Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。
和 C 语言的 for 一样:
for init; condition; post
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
和 C 的 while 一样:
for condition
和 C 的 for(;;)
一样:
for
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for key, value := range oldMap
newMap[key] = value
计算 1 到 10 的数字之和:
package main
import "fmt"
func main()
sum := 0
for i := 0; i <= 10; i++
sum += i
fmt.Println(sum)
init 和 post 参数是可选的,我们可以直接省略它,类似 While 语句。
package main
import "fmt"
func main()
sum := 1
for ; sum <= 10;
sum += sum
fmt.Println(sum)
// 这样写也可以,更像 While 语句形式
for sum <= 10
sum += sum
fmt.Println(sum)
无限循环:要停止无限循环,可以在命令窗口按下ctrl-c 。
package main
import "fmt"
func main()
sum := 0
for
sum++ // 无限循环下去
fmt.Println(sum) // 无法输出
For-each range 循环
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for key, value := range oldMap
newMap[key] = value
package main
import "fmt"
func main()
strings := []string"google", "runoob"
for i, s := range strings
fmt.Println(i, s)
numbers := [6]int1, 2, 3, 5
for i,x:= range numbers
fmt.Printf("第 %d 位 x 的值 = %d\\n", i,x)
以上实例运行输出结果为:
0 google
1 runoob
第 0 位 x 的值 = 1
第 1 位 x 的值 = 2
第 2 位 x 的值 = 3
第 3 位 x 的值 = 5
第 4 位 x 的值 = 0
第 5 位 x 的值 = 0
Go语言函数
Go 语言函数定义格式如下:
func function_name( [parameter list] ) [return_types]
函数体
package main
import "fmt"
func main()
/* 定义局部变量 */
var a int = 100
var b int = 200
var ret int
/* 调用函数并返回最大值 */
ret = max(a, b)
fmt.Printf( "最大值是 : %d\\n", ret )
/* 函数返回两个数的最大值 */
func max(num1, num2 int) int
/* 定义局部变量 */
var result int
if (num1 > num2)
result = num1
else
result = num2
return result
函数返回多个值
package main
import "fmt"
func swap(x, y string) (string, string)
return y, x
func main()
a, b := swap("Google", "Runoob")
fmt.Println(a, b)
以上实例执行结果为:
Runoob Google
语言函数引用传递值
引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
引用传递指针参数传递到函数内,以下是交换函数 swap() 使用了引用传递:
允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。
package main
import "fmt"
func main()
/* 定义局部变量 */
var a int = 100
var b int= 200
fmt.Printf("交换前,a 的值 : %d\\n", a )
fmt.Printf("交换前,b 的值 : %d\\n", b )
/* 调用 swap() 函数
* &a 指向 a 指针,a 变量的地址
* &b 指向 b 指针,b 变量的地址
*/
swap(&a, &b)
fmt.Printf("交换后,a 的值 : %d\\n", a )
fmt.Printf("交换后,b 的值 : %d\\n", b )
func swap(x *int, y *int)
var temp int
temp = *x /* 保存 x 地址上的值 */
*x = *y /* 将 y 值赋给 x */
*y = temp /* 将 temp 值赋给 y */
以上代码执行结果为:
交换前,a 的值 : 100
交换前,b 的值 : 200
交换后,a 的值 : 200
交换后,b 的值 : 100
Go语言数组
Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:
var variable_name [SIZE] variable_type
var balance [10] float32
var balance = [5]float321000.0, 2.0, 3.4, 7.0, 50.0
如果数组长度不确定,可以使用 … 代替数组的长度,编译器会根据元素个数自行推断数组的长度:
var balance = [...]float321000.0, 2.0, 3.4, 7.0, 50.0
或
balance := [...]float321000.0, 2.0, 3.4, 7.0, 50.0
如果设置了数组的长度,我们还可以通过指定下标来初始化元素:
// 将索引为 1 和 3 的元素初始化
balance := [5]float321:2.0,3:7.0
1:2 3:7
访问数组元素
var salary float32 = balance[9]
package main
import "fmt"
func main()
var n [10]int /* n 是一个长度为 10 的数组 */
var i,j int
/* 为数组 n 初始化元素 */
for i = 0; i < 10; i++
n[i] = i + 100 /* 设置元素为 i + 100 */
/* 输出每个数组元素的值 */
for j = 0; j < 10; j++
fmt.Printf("Element[%d] = %d\\n", j, n[j] )
Go语言指针
什么是指针?
一个指针变量指向了一个值的内存地址。
类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
var var_name *var-type
var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明:
var ip *int /* 指向整型*/
var fp *float32 /* 指向浮点型 */
如何使用指针?
指针使用流程:
- 定义指针变量。
- 为指针变量赋值。
- 访问指针变量中指向地址的值。
在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。
package main
import "fmt"
func main()
var a int= 20 /* 声明实际变量 */
var ip *int /* 声明指针变量 */
ip = &a /* 指针变量的存储地址 */
fmt.Printf("a 变量的地址是: %x\\n", &a )
/* 指针变量的存储地址 */
fmt.Printf("ip 变量储存的指针地址: %x\\n", ip )
/* 使用指针访问值 */
fmt.Printf("*ip 变量的值: %d\\n", *ip )
空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
package main
import "fmt"
func main()
var ptr *int
fmt.Printf("ptr 的值为 : %x\\n", ptr )
输出结果:ptr 的值为 : 0
空指针判断:
if(ptr != nil) /* ptr 不是空指针 */
if(ptr == nil) /* ptr 是空指针 */
整型指针数组
指向指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:
指向指针的指针变量声明格式如下:
var ptr **int; // 访问指向指针的指针变量值需要使用两个 * 号
package main
import "fmt"
func main()
var a int
var ptr *int
var pptr **int
a = 3000
/* 指针 ptr 地址 */
ptr = &a
/* 指向指针 ptr 地址 */
pptr = &ptr
/* 获取 pptr 的值 */
fmt.Printf("变量 a = %d\\n", a )
fmt.Printf("指针变量 *ptr = %d\\n", *ptr )
fmt.Printf("指向指针的指针变量 **pptr = %d\\n", **pptr)
以上实例执行输出结果为:
变量 a = 3000
指针变量 *ptr = 3000
指向指针的指针变量 **pptr = 3000
Go语言结构体
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
定义结构体:
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
type struct_variable_type struct
member definition
member definition
...
member definition
一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:
variable_name := structure_variable_type value1, value2...valuen
或
variable_name := structure_variable_type key1: value1, key2: value2..., keyn: valuen
package main
import "fmt"
type Books struct
title string
author string
subject string
book_id int
func main()
// 创建一个新的结构体
fmt.Println(Books"Go 语言", "www.runoob.com", "Go 语言教程", 6495407)
// 也可以使用 key => value 格式
fmt.Println(Bookstitle: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407)
// 忽略的字段为 0 或 空
fmt.Println(Bookstitle: "Go 语言", author: "www.runoob.com")
输出结果为:
Go 语言 www.runoob.com Go 语言教程 6495407
Go 语言 www.runoob.com Go 语言教程 6495407
Go 语言 www.runoob.com 0
访问结构体成员:
如果要访问结构体成员,需要使用点号 . 操作符,格式为:
结构体.成员名
package main
import "fmt"
type Books struct
title string
author string
subject string
book_id int
func main()
var Book1 Books /* 声明 Book1 为 Books 类型 */
var Book2 Books /* 声明 Book2 为 Books 类型 */
/* book 1 描述 */
Book1.title = "Go 语言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 语言教程"
Book1.book_id = 6495407
/* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 语言教程"
Book2.book_id = 6495700
/* 打印 Book1 信息 */
fmt.Printf( "Book 1 title : %s\\n", Book1.title)
fmt.Printf( "Book 1 author : %s\\n", Book1.author)
fmt.Printf( "Book 1 subject : %s\\n", Book1.subject)
fmt.Printf( "Book 1 book_id : %d\\n", Book1.book_id)
/* 打印 Book2 信息 */
fmt.Printf( "Book 2 title : %s\\n", Book2.title)
fmt.Printf( "Book 2 author : %s\\n", Book2.author)
fmt.Printf( "Book 2 subject : %s\\n", Book2.subject)
fmt.Printf( "Book 2 book_id : %d\\n", Book2.book_id)
结构体作为函数参数
package main
import "fmt"
type Books struct
title string
author string
subject string
book_id int
func main()
var Book1 Books /* 声明 Book1 为 Books 类型 */
var Book2 Books /* 声明 Book2 为 Books 类型 */
/* book 1 描述 */
Book1.title = "Go 语言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 语言教程"
Book1.book_id = 6495407
/* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 语言教程"
Book2.book_id = 6495700
/* 打印 Book1 信息 */
printBook(Book1)
/* 打印 Book2 信息 */
printBook(Book2)
func printBook( book Books )
fmt.Printf( "Book title : %s\\n", book.title)
fmt.Printf( "Book author : %s\\n", book.author)
fmt.Printf( "Book subject : %s\\n", book.subject)
fmt.Printf( "Book book_id : %d\\n", book.book_id)
结构体指针
/* 打印 Book2 信息 */
printBook(&Book2)
func printBook( book *Books ) <以上是关于Go语言学习之路的主要内容,如果未能解决你的问题,请参考以下文章