700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Go语言 基础语法学习 (未完待更......

Go语言 基础语法学习 (未完待更......

时间:2019-05-25 13:27:45

相关推荐

Go语言 基础语法学习 (未完待更......

文章目录

一 Go语言结构1 Go Hello world实例2 执行Go程序二 Go语言基础语法1 Go标记2 行分隔符3 注释4 标识符5 一些关键字6 Go语言的空格7 格式化字符串三 Go语言数据类型1 数据类型四 Go语言变量五 Go语言常量六 Go语言运算符1 算术运算符2 关系运算符3 逻辑运算符4 位运算符5 赋值运算符6 其他运算符7 运算符优先级七 Go语言条件语句八 Go语言循环语句九 Go语言函数十 Go语言变量作用域十一 Go语言数组十二 Go语言指针十三 Go语言结构体十四 Go语言切片Slice十五 Go语言范围Range十六 Go语言Map十七 Go语言递归函数十八 Go语言类型转换十九 Go语言接口二十 Go 语言错误处理二十一 Go 语言并发二十二 Go语言开发工具

一 Go语言结构

1 Go Hello world实例

Go 语言的基础组成有以下几个部分:

包声明

引入包

函数

变量

语句 & 表达式

注释

代码示例:

package mainimport "fmt"func main() {/* 这是我的第一个简单的程序 */fmt.Println("Hello, World!")}在这里插入代码片

让我们来看下以上程序的各个部分:

1.**第一行代码 package main 定义了包名。**你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。

package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

2.下一行import “fmt”告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。

3.下一行 func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。

4.下一行 /…/ 是注释,在程序执行时将被忽略。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。

5.下一行 fmt.Println(…) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。

使用 fmt.Print(“hello, world\n”) 可以得到相同的结果。

Print 和 Println 这两个函数也支持使用变量,如:fmt.Println(arr)。如果没有特别指定,它们会以默认的打印格式将变量 arr 输出到控制台。

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。

2 执行Go程序

让我们来看下如何编写 Go 代码并执行它。步骤如下:

打开编辑器如Sublime2,将以上代码添加到编辑器中。

将以上代码保存为 hello.go

打开命令行,并进入程序文件保存的目录中。

输入命令 go run hello.go 并按回车执行代码。

如果操作正确你将在屏幕上看到 “Hello World!” 字样的输出。

$ go run hello.goHello, World!在这里插入代码片

我们还可以使用 go build 命令来生成二进制文件:

$ go build hello.go $ lshello hello.go$ ./hello Hello, World!在这里插入代码片

另外:在Ubuntu 下由vim创建一个go程序,在安装好golang-go后也是可以实现go程序的运行的。如下:

二 Go语言基础语法

1 Go标记

Go 程序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号。

如以下 GO 语句由 6 个标记组成:

fmt.Printn("Hello,World!")

这6个标记是:1. fmt2. .3. Println4. (5. "Hello, World!"6. )在这里插入代码片

2 行分隔符

在 Go 程序中,**一行代表一个语句结束。**每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。

如果你打算将多个语句写在同一行,它们则必须使用 ;人为区分,但在实际开发中我们并不鼓励这种做法。

以下为两个语句:

fmt.Println("Hello, World!")fmt.Println("你好世界!")在这里插入代码片

3 注释

注释不会被编译,每一个包应该有相关注释。貌似添加注释的方式和C++一致

单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。如:

//单行注释的方式/*你好世界我是多行注释*/在这里插入代码片

4 标识符

标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(AZ和az)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。

以下是有效的标识符:

mahesh kumar abc move_name a_123myname50 _temp j a23b9 retVal在这里插入代码片

以下是无效的标识符:

1ab(以数字开头)case(Go 语言的关键字)a+b(运算符是不允许的)在这里插入代码片

字符串连接:

Go语言中连接字符串使用+实现:

package mainimport "fmt"func main() {fmt.Println("zhang" + "liang")}在这里插入代码片

5 一些关键字

25个关键字或保留字

36个预定义标识符

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6 Go语言的空格

Go 语言中变量的声明必须使用空格隔开,如:

var age int;在这里插入代码片

语句中适当使用空格能让程序更易阅读。

fruit=apples+oranges;fruit = apples + oranges; //更加美观在这里插入代码片

7 格式化字符串

Go 语言中使用 fmt.Sprintf 格式化字符串并赋值给新串:`

package mainimport ("fmt")func main() {// %d 表示整型数字,%s 表示字符串var stockcode=123var enddate="-12-31"var url="Code=%d&endDate=%s"var target_url=fmt.Sprintf(url,stockcode,enddate)fmt.Println(target_url)}输出结果:Code=123&endDate=-12-31在这里插入代码片

三 Go语言数据类型

Go语言中,数据类型用于生命函数和变量;

数据类型的出现是为了把数据分为所需内存大小不同的数据,编程的时候需要用大数据才需要申请大内存。

Go语言中有以下几种数据类型:

1 数据类型

Go也有基于架构的类型 如:int ,uint, nintptr

浮点型:

其他数字类型:

四 Go语言变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。

变量可以通过变量名访问

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用var 关键字

var identifier type

还可以一次声明多个变量:

var identifier1,identifier2 type在这里插入代码片

引入一个示例:

package mainimport "fmt"func main(){//这里括号必须紧挨着大括号 否则无法运行var a string="Runoob"fmt.Println(a)var b,c int=1,2fmt.Println(b,c)}示例输出结果:Runoob1 2 在这里插入代码片

变量声明

第一种 指定变量类型 如果没有初始化 则变量默认为0

var v_name v_typev_name=value在这里插入代码片

零值就是变量没有初始化时系统默认设置的值

paceage mainimport "fmt"func main(){var a="RUNNOB"//声明一个变量并初始化fmt.Println(a)//没有初始化就为零值var b intfmt.Println(b)//bool 零值为falsevar c boolfmt.Println(c)}示例执行结果为:RUNOOB0false在这里插入代码片

数值类型(包括complex64/128)为0

布尔类型false

字符串" "空字符串

以下几种类型为nil:

var a *intvar a []intvar a map[string] intvar a chan intvar a func(string) intvar a error // error 是接口在这里插入代码片

引入示例:

package mainimport "fmt"func main(){var i intvar f float64var b bool var s stringfmt.Printf("%v %v %v %q\n",i,f,b,s)}输出结果是:0 0 false ""在这里插入代码片

第二种 根据值自行判定变量类型

var v_name=value在这里插入代码片

package mainimport "fmt"func main() {var d = truefmt.Println(d)}输出结果为:true在这里插入代码片

第三种 如果变量已经使用了var声明过了 再使用:=声明变量 就产生编译错误 格式

v_name := value在这里插入代码片

例如:

var intVal intintVal :=1在这里插入代码片

直接使用下面的语句即可:

intVal := 1 //

intval :=1相当于:

var intVal intintVal =1

可以将 var f string = “Runoob” 简写为 f := “Runoob”:

引入示例:

package mainimport "fmt"func main() {f := "Runoob" // var f string = "Runoob"fmt.Println(f)}输出结果是:Runoob在这里插入代码片

多变量声明

//类型相同多个变量, 非全局变量var vname1, vname2, vname3 typevname1, vname2, vname3 = v1, v2, v3var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误// 这种因式分解关键字的写法一般用于声明全局变量var (vname1 v_type1vname2 v_type2)在这里插入代码片

引入一个示例:

package mainvar x, y intvar ( // 这种因式分解关键字的写法一般用于声明全局变量a intb bool)var c, d int = 1, 2var e, f = 123, "hello"//这种不带声明格式的只能在函数体中出现//g, h := 123, "hello"func main(){g, h := 123, "hello"println(x, y, a, b, c, d, e, f, g, h)}输出结果是:0 0 0 false 1 2 123 hello 123 hello在这里插入代码片

值类型和引用类型

所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值

你可以通过 &i 来获取变量 i 的内存地址,例如:0xf840000040(每次的地址都可能不一样)。

值类型变量的值存储在堆中。

内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同。

更复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存。

一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置

这个内存地址称之为指针,这个指针实际上也被存在另外的某一个值中。

同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址。

当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。

如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响

简短形式,使用 := 赋值操作符

我们知道可以在变量的初始化时省略变量的类型而由系统自动推断,声明语句写上 var 关键字其实是显得有些多余了,因此我们可以将它们简写为 a := 50 或 b := false。

a 和 b 的类型(int 和 bool)将由编译器自动推断。

这是使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明。

注意事项

如果在相同的代码块中,我们不可以再次对于相同名称的变量使用初始化声明,例如:a := 20 就是不被允许的,编译器会提示错误 no new variables on left side of :=,但是 a = 20 是可以的,因为这是给相同的变量赋予一个新的值。

如果你在定义变量 a 之前使用它,则会得到编译错误 undefined: a。

如果你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误,例如下面这个例子当中的变量 a

引入示例:

package mainimport "fmt"func main() {var a string = "abc"fmt.Println("hello, world")}在这里插入代码片

尝试编译这段代码将得到错误 a declared and not used。

此外,单纯地给 a 赋值也是不够的,这个值必须被使用,所以使用

fmt.Println("hello, world", a)在这里插入代码片

会移除错误。

但是全局变量是允许声明但不使用的。 同一类型的多个变量可以声明在同一行,如:

var a, b, c int在这里插入代码片

多变量可以在同一行进行赋值,如:

var a, b intvar c stringa, b, c = 5, 7, "abc"在这里插入代码片

上面这行假设了变量 a,b 和 c 都已经被声明,否则的话应该这样使用

a, b, c := 5, 7, "abc"在这里插入代码片

右边的这些值以相同的顺序赋值给左边的变量,所以 a 的值是 5, b 的值是 7,c 的值是 “abc”。

这被称为 并行 或 同时 赋值。

如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a,两个变量的类型必须是相同。

空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。

_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。

并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)。

五 Go语言常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式:

const indentifier [type] = value

可以省略类型说明符[type] 因为编译器可以根据变量的值来推断其类型

显示类型定义:const b string = "abc“隐式类型定义:const b = "abc"

多种相同类型的声明可以简写为:

const c_name1,c_name2=value1,value2

用代码实例演示常量的应用:

package mainimport "fmt"func main() {const LENGTH int = 10const WIDTH int = 5 var area intconst a, b, c = 1, false, "str" //多重赋值area = LENGTH * WIDTHfmt.Printf("面积为 : %d", area)println()println(a, b, c) }输出结果为:面积为:501 false str

常量还可以用作枚举:

const(Unkonwn = 0Female = 1Male = 2

常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:

实例如下:

package mainimport "unsafe"const (a = "abc"b = len(a)c = unsafe.Sizeof(a))func main(){println(a, b, c)}输出:abc 3 16

iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

iota 可以被用作枚举值:

const (a = iotab = iotac = iota)

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式

const(a = itoabc)

itoa 用法

package mainimport "fmt"func main() {const (a = iota //0b//1c//2d = "ha" //独立值,iota += 1e//"ha" iota += 1f = 100 //iota +=1g//100 iota +=1h = iota //7,恢复计数i//8)fmt.Println(a,b,c,d,e,f,g,h,i)}输出结果为:0 1 2 ha ha 100 100 7 8

再引入一个itoa的实例:

package mainimport "fmt"const (i=1<<iota //i=1<<0 itoa表示从0开始自动加1j=3<<iota //j=3<<1 3的二进制左移一位:00000011->00000110 k//k=3<<2 3的二进制左移两位:00000011->00001100l//l=3<<3 3的二进制左移三位:00000011->00001100)func main() {fmt.Println("i=",i)fmt.Println("j=",j)fmt.Println("k=",k)fmt.Println("l=",l)}输出结果为:i=1j=6k=12l=24

六 Go语言运算符

运算符用于在程序运行时执行数学或逻辑运算。

Go 语言内置的运算符有:

算术运算符

关系运算符

逻辑运算符

位运算符

赋值运算符

其他运算符

接下来让我们来详细看看各个运算符的介绍。

1 算术运算符

下表中 假设A=10 B=20

代码实现:

package mainimport "fmt"func main() {var a int = 21var b int = 10var c intc = a + bfmt.Printf("第一行 - c 的值为 %d\n", c )c = a - bfmt.Printf("第二行 - c 的值为 %d\n", c )c = a * bfmt.Printf("第三行 - c 的值为 %d\n", c )c = a / bfmt.Printf("第四行 - c 的值为 %d\n", c )c = a % bfmt.Printf("第五行 - c 的值为 %d\n", c )a++fmt.Printf("第六行 - a 的值为 %d\n", a )a=21 // 为了方便测试,a 这里重新赋值为 21a--fmt.Printf("第七行 - a 的值为 %d\n", a )}输出:第一行 - c 的值为 31第二行 - c 的值为 11第三行 - c 的值为 210第四行 - c 的值为 2第五行 - c 的值为 1第六行 - a 的值为 22第七行 - a 的值为 20

2 关系运算符

假定A=10 B=20

代码实现:

package mainimport "fmt"func main() {var a int = 21var b int = 10if( a == b ) {fmt.Printf("第一行 - a 等于 b\n" )} else {fmt.Printf("第一行 - a 不等于 b\n" )}if ( a < b ) {fmt.Printf("第二行 - a 小于 b\n" )} else {fmt.Printf("第二行 - a 不小于 b\n" )}if ( a > b ) {fmt.Printf("第三行 - a 大于 b\n" )} else {fmt.Printf("第三行 - a 不大于 b\n" )}/* Lets change value of a and b */a = 5b = 20if ( a <= b ) {fmt.Printf("第四行 - a 小于等于 b\n" )}if ( b >= a ) {fmt.Printf("第五行 - b 大于等于 a\n" )}}输出:第一行 - a 不等于 b第二行 - a 不小于 b第三行 - a 大于 b第四行 - a 小于等于 b第五行 - b 大于等于 a

3 逻辑运算符

假定A=true B=False

代码实现:

package mainimport "fmt"func main() {var a bool = truevar b bool = falseif ( a && b ) {fmt.Printf("第一行 - 条件为 true\n" )}if ( a || b ) {fmt.Printf("第二行 - 条件为 true\n" )}/* 修改 a 和 b 的值 */a = falseb = trueif ( a && b ) {fmt.Printf("第三行 - 条件为 true\n" )} else {fmt.Printf("第三行 - 条件为 false\n" )}if ( !(a && b) ) {fmt.Printf("第四行 - 条件为 true\n" )}}输出:第二行 - 条件为 true第三行 - 条件为 false第四行 - 条件为 true

4 位运算符

假定A=60;B=13A = 0011 1100B = 0000 1101-----------------A&B = 0000 1100A|B = 0011 1101A^B = 0011 0001

代码实现:

package mainimport "fmt"func main() {var a uint = 60/* 60 = 0011 1100 */ var b uint = 13/* 13 = 0000 1101 */var c uint = 0c = a & b /* 12 = 0000 1100 */fmt.Printf("第一行 - c 的值为 %d\n", c )c = a | b /* 61 = 0011 1101 */fmt.Printf("第二行 - c 的值为 %d\n", c )c = a ^ b /* 49 = 0011 0001 */fmt.Printf("第三行 - c 的值为 %d\n", c )c = a << 2/* 240 = 1111 0000 */fmt.Printf("第四行 - c 的值为 %d\n", c )c = a >> 2/* 15 = 0000 1111 */fmt.Printf("第五行 - c 的值为 %d\n", c )}

输出为:

第一行 - c 的值为 12

第二行 - c 的值为 61

第三行 - c 的值为 49

第四行 - c 的值为 240

第五行 - c 的值为 15

5 赋值运算符

代码实现:

package mainimport "fmt"func main() {var a int = 21var c intc = afmt.Printf("第 1 行 - = 运算符实例,c 值为 = %d\n", c )c += afmt.Printf("第 2 行 - += 运算符实例,c 值为 = %d\n", c )c -= afmt.Printf("第 3 行 - -= 运算符实例,c 值为 = %d\n", c )c *= afmt.Printf("第 4 行 - *= 运算符实例,c 值为 = %d\n", c )c /= afmt.Printf("第 5 行 - /= 运算符实例,c 值为 = %d\n", c )c = 200;c <<= 2fmt.Printf("第 6行 - <<= 运算符实例,c 值为 = %d\n", c )c >>= 2fmt.Printf("第 7 行 - >>= 运算符实例,c 值为 = %d\n", c )c &= 2fmt.Printf("第 8 行 - &= 运算符实例,c 值为 = %d\n", c )c ^= 2fmt.Printf("第 9 行 - ^= 运算符实例,c 值为 = %d\n", c )c |= 2fmt.Printf("第 10 行 - |= 运算符实例,c 值为 = %d\n", c )}

输出结果:

第 1 行 - = 运算符实例,c 值为 = 21

第 2 行 - += 运算符实例,c 值为 = 42

第 3 行 - -= 运算符实例,c 值为 = 21

第 4 行 - *= 运算符实例,c 值为 = 441

第 5 行 - /= 运算符实例,c 值为 = 21

第 6行 - <<= 运算符实例,c 值为 = 800

第 7 行 - >>= 运算符实例,c 值为 = 200

第 8 行 - &= 运算符实例,c 值为 = 0

第 9 行 - ^= 运算符实例,c 值为 = 2

第 10 行 - |= 运算符实例,c 值为 = 2

6 其他运算符

代码实现:

package mainimport "fmt"func main() {var a int = 4var b int32var c float32var ptr *int/* 运算符实例 */fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a );fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b );fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c );/* & 和 * 运算符实例 */ptr = &a/* 'ptr' 包含了 'a' 变量的地址 */fmt.Printf("a 的值为 %d\n", a);fmt.Printf("*ptr 为 %d\n", *ptr);}输出:

第 1 行 - a 变量类型为 = int

第 2 行 - b 变量类型为 = int32

第 3 行 - c 变量类型为 = float32

a 的值为 4

*ptr 为 4

7 运算符优先级

代码实现:

package mainimport "fmt"func main() {var a int = 20var b int = 10var c int = 15var d int = 5var e int;e = (a + b) * c / d;// ( 30 * 15 ) / 5fmt.Printf("(a + b) * c / d 的值为 : %d\n", e );e = ((a + b) * c) / d; // (30 * 15 ) / 5fmt.Printf("((a + b) * c) / d 的值为 : %d\n" , e );e = (a + b) * (c / d); // (30) * (15/5)fmt.Printf("(a + b) * (c / d) 的值为 : %d\n", e );e = a + (b * c) / d;// 20 + (150/5)fmt.Printf("a + (b * c) / d 的值为 : %d\n" , e ); }输出结果为:(a + b) * c / d 的值为 : 90((a + b) * c) / d 的值为 : 90(a + b) * (c / d) 的值为 : 90a + (b * c) / d 的值为 : 50

七 Go语言条件语句

八 Go语言循环语句

九 Go语言函数

十 Go语言变量作用域

十一 Go语言数组

十二 Go语言指针

十三 Go语言结构体

十四 Go语言切片Slice

十五 Go语言范围Range

十六 Go语言Map

十七 Go语言递归函数

十八 Go语言类型转换

十九 Go语言接口

二十 Go 语言错误处理

二十一 Go 语言并发

二十二 Go语言开发工具

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。