以下使用goland的IDE演示,包含总计的golang基础功能共20个章节
四、常量
五、运算符
六、条件语句
七、循环
八、函数
九、变量作用域
十、数组
十一、指针
十二、结构体
十三、切片
十四、范围(Range)
十五、集合
十六、递归
十七、数据类型转换
十八、接口
十九、错误处理
二十、并发
 
 
一、go语言结构:
1.运行Hello World!
package main

import "fmt"

func main() {
fmt.Println("Hello World!")
}
查看运行结果:
2.语言结构:
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 输出到控制台。
6. 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
 
二、go基础语法:
1.行分隔符:
Println函数会在行末尾自动加上换行符
package main

import "fmt"

func main() {
fmt.Println("Hello World!")
fmt.Println("Println函数会在行末尾自动加上换行符")
}
查看运行结果:
2.注释:
单行注释以//开头,多行注释以 /* 开头,并以 */ 结尾
// 单行注释
/*
我说多行注释1
我说多行注释2
我说多行注释3
*/
3.标识符:
标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
以下是有效的标识符:
mahesh   kumar   abc   move_name   a_123
myname50   _temp   j   a23b9   retVal
以下是无效的标识符:
* 1ab(以数字开头)
* case(Go 语言的关键字)
* a+b(运算符是不允许的)
4.字符串连接:
Go 语言的字符串连接可以通过 + 实现:
import "fmt"

func main() {
fmt.Println("golang"+"python")
}
查看运行结果:
5.关键字:
下面列举了 Go 代码中会使用到的 25 个关键字或保留字:
break default func interface select
case defer go map struct 
chan else goto package switch
const fallthrough if range type
continue for import return var
6.格式化字符串:
// 常用的使用%d 表示整型数字,%s 表示字符串

package main

import "fmt"

func main() {
//fmt.Println("Hello World!")
//fmt.Println("Println函数会在行末尾自动加上换行符")
//fmt.Println("golang" + "python")
var today = "星期六"
var number = 6
fmt.Printf("今天是%s,今天在本周的排号为%d", today, number)
}
查看运行结果:
 
三、变量
1、申明一个变量值,变量类型,并初始化
(1)两种方式,方式1:使用var声明
package main

func main() {
var str string = "hello"
var num int = 123
println(str, num)
}
查看运行结果:
(2)使用:=声明
package main

func main() {
//var str string = "hello"
//var num int = 123
//println(str, num)
mystr := "very good"
mynum := 345
println(mystr, mynum) }
查看运行结果:
2、申请变量未初始化,则会给默认值
数值类型初始值0
布尔类型为fasle
字符串为""
其他类型为nil
func main() {
//var str string = "hello"
//var num int = 123
//println(str, num) //初始值0
var num1 int
fmt.Println("num1初始值为:", num1)
//初始值""
var str1 string
fmt.Println("str1初始值为:", str1)
//布尔类型为 false
var flag bool
fmt.Println("flag初始值为:", flag)
//其他类型为nil
var a *int
var b []int
var c map[string]int
var d chan int
var e func(string) int
var f error
fmt.Println("a,b,c,d,e,f的初始值分别为:", a, b, c, d, e, f)
}
查看运行结果:
3、根据值自行判定变量类型
package main

import (
"fmt"
"reflect"
) func main() { var str2 = "hello"
var num2 = 25
var flag2 = true
fmt.Println("str2的类型为:", reflect.TypeOf(str2))
fmt.Println("num2的类型为:", reflect.TypeOf(num2))
fmt.Println("flag2的类型为:", reflect.TypeOf(flag2))
}
查看运行结果:
4、多变量声明:
使用逗号隔开
package main

import "fmt"

func main() {

var str3, str4, str5 string = "hello", "World", "ok"
num3, num4, num5 := 2, 3, 4
fmt.Println(str3, str4, str5)
fmt.Println(num3, num4, num5) }
查看运行结果:
5、引用类型变量
&可查看引用变量的地址
package main

import "fmt"

func main() {

var a1 = 10
var b1 = "ok"
fmt.Println("a1=", a1)
fmt.Println("b1=", b1)
fmt.Println("a1=", &a1)
fmt.Println("b1=", &b1)
}
查看运行结果:
 
四、常量
1.常量定义:
常量是一个简单值的标识符,在程序运行时,不会被修改的量,使用const修饰一个常量
package main

func main() {
const a string = "abc" //显示类型定义
const b = "abc" //隐示类型定义
const c, d = "o", "k"
println(a, b, c, d)
}
查看运行结果:
2. 常量还可以用作枚举:
并且常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过
package main

import "unsafe"

func main() {
//const a string = "abc" //显示类型定义
//const b = "abc" //隐示类型定义
//const c, d = "o", "k"
//println(a, b, c, d)
const (
Unknown = 0
Female = 1
Male = 2
) const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a) //16个字节,返回string结构体的字符与长度各8个字符相加
)
println(Unknown, Female, Male, a, b, c)
}
查看运行结果:
3.特殊常量iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
package main

func main() {

const (
a = iota
b
c
)
println(a, b, c)
}
查看运行结果:
package main

import "fmt"

func main() {

//println(a, b, c)
const (
a = iota //0
b //1
c //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a, b, c, d, e, f, g, h, i)
}
查看运行结果:
 
五、运算符
1.算数运算符:
package main

import "fmt"

func main() {
a := 1
b := 2
fmt.Println("a加b等于:", a+b)
fmt.Println("a减b等于:", a-b)
fmt.Println("a剩b等于:", a*b)
fmt.Println("a除b等于:", a/b)
fmt.Println("a除b后取余数等于:", a%b)
a++
fmt.Println("a++后的结果:", a)
b--
fmt.Println("b--后的结果:", b)
}
查看运行结果:
2.关系运算符
关系运算符主要有 =,!=,>,<,>=,<=共6种运算符
package main

import "fmt"

func main() {

var m int = 21
var n int = 10
if m == n {
fmt.Println("第一行返回:a等于b")
} else {
fmt.Println("第一行返回:a不等于b")
}
if m < n {
fmt.Println("第二行返回:a小于b")
} else {
fmt.Println("第二行返回:a不小于b")
}
if m > n {
fmt.Println("第三行返回:a大于b")
} else {
fmt.Println("第三行返回:a不大于b")
}
m, n = n, m //交换m,n的值
if m <= n {
fmt.Println("第四行返回:a小于等于b")
}
if m >= n {
fmt.Println("第四行返回:a不小于b")
}
}
查看运行结果:
3.逻辑运算符
主要有三种逻辑运算符:
&&:逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。
||:逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。
!:逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。
package main

import "fmt"

func main() {

var a bool = true
var b bool = false
if a && b {
fmt.Printf("第一行 - 条件为 true\n")
} else if a || b {
fmt.Printf("第一行 - 条件为 true\n")
}
a, b = b, a //修改a,b的值,对调
if a && b {
fmt.Printf("第二行 - 条件为 true\n")
} else {
fmt.Printf("第二行 - 条件为 false\n")
}
if !(a && b) {
fmt.Printf("第三行 - 条件为 true\n")
} else {
fmt.Printf("第三行 - 条件为 false\n")
} }
查看运行结果:
4.位运算符
位运算符对整数在内存中的二进制位进行操作。
 &, |,  ^ ,<<,>>四种位运算方式
package main

import "fmt"

func main() {

var a uint = 60 /* 60 = 0011 1100 */
var b uint = 13 /* 13 = 0000 1101 */
var c uint = 0 c = 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) }
查看运行结果:
5.赋值运算符
赋值符号为=,将一个表达式的值赋给一个左值,结合之前其他的型号的赋值运算符如下:
package main

import "fmt"

func main() {

var a int = 21
var c int c = a
fmt.Printf("第 1 行 - = 运算符实例,c 值为 = %d\n", c) c += a
fmt.Printf("第 2 行 - += 运算符实例,c 值为 = %d\n", c) c -= a
fmt.Printf("第 3 行 - -= 运算符实例,c 值为 = %d\n", c) c *= a
fmt.Printf("第 4 行 - *= 运算符实例,c 值为 = %d\n", c) c /= a
fmt.Printf("第 5 行 - /= 运算符实例,c 值为 = %d\n", c) c = 200 c <<= 2
fmt.Printf("第 6行 - <<= 运算符实例,c 值为 = %d\n", c) c >>= 2
fmt.Printf("第 7 行 - >>= 运算符实例,c 值为 = %d\n", c) c &= 2
fmt.Printf("第 8 行 - &= 运算符实例,c 值为 = %d\n", c) c ^= 2
fmt.Printf("第 9 行 - ^= 运算符实例,c 值为 = %d\n", c) c |= 2
fmt.Printf("第 10 行 - |= 运算符实例,c 值为 = %d\n", c)
}
查看运行结果:
 
六、条件语句
1.if else语句:
package main

import "fmt"

func main() {
//if else语句
age := 18
if age < 5 {
fmt.Println("你的age为:", age, ",你太小了无法进入")
} else if age < 18 {
fmt.Println("你的age为:", age, ",你虽然不小了,但是仍然未满18,无法进入")
} else {
fmt.Println("你的age为:", age, ",你已满18岁,可以进入")
}
}
查看运行结果:
2.if嵌套语句
计算可以数字a在0-100内,且是否可以被5整除
package main

import "fmt"

func main() {

a := 100
//if嵌套
if a <= 100 {
fmt.Println("a的值符合条件1:在0~100内,为:", a)
if a%5 == 0 {
fmt.Println("a的值符合条件2:可以被5整除,为:", a)
} else {
fmt.Println("a的值不符合条件2:不可以被5整除,为:", a) }
} else {
fmt.Println("a的值不符合条件1:非在0~100内,为:", a) }
}
查看运行结果:
3.switch语句
(1)switch+case语句:
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。
witch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case
package main

import "fmt"

func main() {

//3.switch case语句
score := 75
var grade string
switch {
case score < 60:
grade = "C"
case score >= 60 && score < 80:
grade = "B"
case score >= 80:
grade = "A"
}
fmt.Println(grade) }
查看运行结果:
(2)switch+case+fallthrough
使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。
package main

import "fmt"

func main() {

score := 95
var grade string
switch {
case score < 60:
grade = "C"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 60 && score < 80:
grade = "B"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 80:
grade = "A"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
}
fmt.Println(grade)
}
查看运行结果:
(3)switch+default:
defalut如果放在哪里是会最后执行
package main

import "fmt"

func main() {

score := 200
var grade string
switch {
default:
grade = "Nothing"
fmt.Printf("你的成绩为%d,并不合法,最终grade为%s", score, grade)
case score < 60:
grade = "C"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 60 && score < 80:
grade = "B"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 80 && score <= 100:
grade = "A"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
} }
查看运行结果:
4.select语句
select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。
select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。
package main

import "fmt"

func main() {

var c1, c2, c3 chan int
var i1, i2 int
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
default:
fmt.Printf("no communication\n")
} }
查看运行结果:
 
七、循环
1.for循环
(1)for condition {}
package main

import "fmt"

func main() {
//1.for condition语句
sum := 0
for i := 1; i <= 10; i++ {
sum += i
}
fmt.Println(sum) //累加1~10
}
查看运行结果:
(2)for init {}
package main

import "fmt"

func main() {

Strings := []string{"google", "golang"}
for m, n := range Strings {
fmt.Println(m, n)
}
}
查看运行结果:
2.循环嵌套
package main

import "fmt"

func main() {

//2.循环嵌套:找到1-30内的素数
var i, j int
for i = 2; i < 30; i++ {
for j = 2; j <= i/j; j++ {
if i%j == 0 {
break
}
}
if j > (i / j) {
fmt.Println(i, "是一个素数")
}
}
}
查看运行结果:
3.break语句
Go 语言中 break 语句用于以下两方面:
(1) 用于循环语句中跳出循环,并开始执行循环之后的语句
//3.1 break跳出循环
var a int = 10
for a < 20 {
fmt.Println("a的值:", a)
a++
if a == 15 {
break
}
}
}
查看运行结果:
(2) break 在 switch(开关语句)中在执行一条 case 后跳出语句的作用。(此break会隐藏)
(3)在多重循环中,可以用标号 label 标出想 break 的循环。
package main

import "fmt"

func main() {

//3.2 break label标出想break的循环
// 不使用标记
fmt.Println("---- break ----")
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
break
}
} // 使用标记
fmt.Println("---- break label ----")
re:
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
break re
}
} }
查看运行结果:
4.continue 语句
Go 语言的 continue 语句 有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。
(1)for 循环中,执行 continue 语句会触发 for 增量语句的执行。
package main

import "fmt"

func main() {

//4.1 continue语句,不是跳出循环,而是跳过当前循环执行下一次循环语句
a := 10
for a < 20 {
a++
if a == 15 {
continue
}
fmt.Println("a的值为:", a)
} }
查看运行结果:
(2)在多重循环中,可以用标号 label 标出想 continue 的循环。
package main

import "fmt"

func main() {

//4.2 使用continue+label标出想 continue 的循环
// 不使用标记
fmt.Println("---- continue ---- ")
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
continue
}
} // 使用标记
fmt.Println("---- continue label ----")
re:
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
continue re
}
} }
查看运行结果:
5.goto 语句
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
package main

import "fmt"

func main() {

//5.goto语句可以无条件地转移到过程中指定的行
/* 定义局部变量 */
var a int = 10 /* 循环 */
LOOP:
for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LOOP
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
}
查看运行结果:
 
八、函数
1.函数定义与调用
Go 语言最少有个 main() 函数。
你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。
函数定义解析:
* func:函数由 func 开始声明
* function_name:函数名称,参数列表和返回值类型构成了函数签名。
* parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
* return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
* 函数体:函数定义的代码集合。
package main

import "fmt"

func main() {
var a int = 98
var b int = 99
var c int = max(a, b)
fmt.Println("a,b两个数的最大值为:", c)
} func max(num1, num2 int) int {
/* 声明局部变量 */
var result int if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
查看运行结果:
2.函数返回多个值
package main

import "fmt"

func main() {

x := "hello"
y := "world"
fmt.Println("交换前的x与y分别为:", x, y)
x, y = swap(x, y)
fmt.Println("交换后的x与y分别为:", x, y)
} func swap(x, y string) (string, string) {
x, y = y, x
return x, y
}
查看运行结果:
3.值传递与引用传递
(1)值传递:
值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
package main

import (
"fmt"
) func main() { x := "hello"
y := "world"
fmt.Println("交换前的x与y分别为:", x, y)
swap(x, y)
fmt.Println("交换后的x与y分别为:", x, y)
} //值传递
func swap(x, y string) string {
var temp string
temp = x
x = y
y = temp
return temp
}
查看运行结果:
(2)引用传递:
引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
package main

import (
"fmt"
) func main() {
//var a int = 98
//var b int = 99
//var c int = max(a, b)
//fmt.Println("a,b两个数的最大值为:", c) x := "hello"
y := "world"
fmt.Println("交换前的x与y分别为:", x, y)
swap(&x, &y)
fmt.Println("交换后的x与y分别为:", x, y)
} //func max(num1, num2 int) int {
// /* 声明局部变量 */
// var result int
//
// if num1 > num2 {
// result = num1
// } else {
// result = num2
// }
// return result
//} ////值传递
//func swap(x, y string) string {
// var temp string
// temp = x
// x = y
// y = temp
// return temp
//} //引用传递
func swap(x, y *string) string {
var temp string
temp = *x
*x = *y
*y = temp
return temp
}
查看运行结果:
4.函数作为另外一个函数的实参(进阶ToDo)
5.闭包(进阶ToDo)
6.方法(进阶ToDo)
 
九、变量作用域
1.局部变量:
* 函数内定义的变量称为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
package main

import "fmt"

func main() {
/* 声明局部变量 */
var a, b, c int /* 初始化参数 */
a = 10
b = 20
c = a + b fmt.Printf("结果: a = %d, b = %d and c = %d\n", a, b, c)
}
查看运行结果:
2.全局变量
* 函数外定义的变量称为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用
package main

import "fmt"

/* 声明全局变量 */
var g int func main() { /* 声明局部变量 */
var a, b int /* 初始化参数 */
a = 10
b = 20
g = a + b fmt.Printf("结果: a = %d, b = %d and g = %d\n", a, b, g)
}
查看运行结果:
3.形式参数
形式参数会作为函数的局部变量来使用。实例如下:
package main

import "fmt"

///* 声明全局变量 */
//var g int /* 声明全局变量 */
var a int = 20 func main() { /* main 函数中声明局部变量 */
var a int = 10
var b int = 20
var c int = 0 fmt.Printf("main()函数中 a = %d\n", a)
c = sum(a, b)
fmt.Printf("main()函数中 c = %d\n", c)
} /* 函数定义-两数相加 */
func sum(a, b int) int {
fmt.Printf("sum() 函数中 a = %d\n", a)
fmt.Printf("sum() 函数中 b = %d\n", b) return a + b
}
查看运行结果:
4.初始化局部和全局变量
不同类型的局部和全局变量的默认值为:
int为0
float32为0
pointer为nil
 
十、数组
1.声明数组
例如以下定义了数组 balance 长度为 10 类型为 float32:
var balance [10] float32
2.初始化数组
package main

import "fmt"

func main() {
//1.初始化数组
balance1 := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
fmt.Println(balance1)
//如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度:
balance2 := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
fmt.Println(balance2)
}
查看运行结果:
3.访问数组元素
package main

import "fmt"

func main() {

//3.访问列表元素,通过for循环方式遍历
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])
}
}
查看运行结果:
4.多维数组(进阶ToDo)
5.向函数传递数组(进阶ToDo)
 
十一、指针
1.指针的使用
一个指针变量指向了一个值的内存地址。
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)
}
查看运行结果:
2.空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr。
package main

import "fmt"

func main() {

//空指针
var ptr *int
fmt.Printf("ptr 的值为 : %x\n", ptr)
}
查看运行结果:
3.指针数组(进阶ToDo)
4.指向指针的指针(进阶ToDo)
5.指针作为函数参数(进阶ToDo)
 
十二、结构体
1.定义结构体
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。
package main

import "fmt"

//定义结构体
type Books struct {
title string
author string
subject string
bookId int
} func main() {
// 创建一个新的结构体
fmt.Println(Books{"Go 语言", "mr.white", "Go语言教程", 100001}) // 也可以使用 key => value 格式
fmt.Println(Books{title: "Go 语言", author: "mr.white", subject: "Go语言教程", bookId: 100002}) // 忽略的字段为 0 或 空
fmt.Println(Books{title: "Go 语言", author: "mr.white"})
}
查看运行结果:
2.访问结构体成员
如果要访问结构体成员,需要使用点号 . 操作符。
package main

import "fmt"

//定义结构体
type Books struct {
title string
author string
subject string
bookId int
} func main() { /* book 1 描述 */
Book1.title = "Go 语言"
Book1.author = "mr.white"
Book1.subject = "Go 语言教程"
Book1.bookId = 100001 /* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "mr.white"
Book2.subject = "Python 语言教程"
Book2.bookId = 100002 /* 打印 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.bookId) /* 打印 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.bookId)
}
查看运行结果:
3.结构体作为函数参数(进阶ToDo)
4.结构体指针(进阶ToDo)
 
十三、切片
1.定义/切片初始化
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
package main

import "fmt"

func main() {
//1.直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3。
s := []int{1, 2, 3}
fmt.Println("切片s:", s)
//初始化切片 s1,是数组 s 的引用。
s1 := s[:]
fmt.Println("切片s1:", s1)
//初始化切片 s2,是从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。
s2 := s[1:3]
fmt.Println("切片s2:", s2)
//使用make初始化切片
s3 := make([]int, 3)
fmt.Println("切片s3:", s3)
}
查看运行结果:
2.len() 和 cap() 函数
len() 方法获取切片的长度
cap()方法 可以测量切片最长可以达到多少
package main

import "fmt"

func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
} func main() { //2调用printSlice方法获取切片的长度与容量
var numbers = make([]int, 3, 5)
printSlice(numbers)
}
查看运行结果:
3.空(nil)切片
package main

import "fmt"

func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
} func main() { //3.空切片
var numbers []int
printSlice(numbers)
if numbers == nil {
fmt.Println("切片是空的呢")
}
}
查看运行结果:
6.切片截取
可以通过设置下限及上限来设置截取切片 [lower-bound:upper-bound],实例如下:
package main

import "fmt"

func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
} func main() { //切片截取举例
/* 创建切片 */
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
printSlice(numbers) /* 打印原始切片 */
fmt.Println("numbers ==", numbers) /* 打印子切片从索引1(包含) 到索引4(不包含)*/
fmt.Println("numbers[1:4] ==", numbers[1:4]) /* 默认下限为 0*/
fmt.Println("numbers[:3] ==", numbers[:3]) /* 默认上限为 len(s)*/
fmt.Println("numbers[4:] ==", numbers[4:]) numbers1 := make([]int, 0, 5)
printSlice(numbers1) /* 打印子切片从索引 0(包含) 到索引 2(不包含) */
number2 := numbers[:2]
printSlice(number2) /* 打印子切片从索引 2(包含) 到索引 5(不包含) */
number3 := numbers[2:5]
printSlice(number3)
}
查看运行结果:
7.append() 和 copy() 函数
如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。
下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。
package main

import "fmt"

func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
} func main() { //5.append() 和 copy() 函数
var numbers []int
printSlice(numbers) /* 允许追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers) /* 向切片添加一个元素 */
numbers = append(numbers, 1)
printSlice(numbers) /* 同时添加多个元素 */
numbers = append(numbers, 2,3,4)
printSlice(numbers) /* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2) /* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
}
查看运行结果:
 
十四、范围(Range)
1.range的作用
range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环
 
2.举例说明
package main

import "fmt"

func main() {
map1 := make(map[int]float32)
map1[1] = 1.0
map1[2] = 2.0
map1[3] = 3.0
map1[4] = 4.0 // 读取 key 和 value
for key, value := range map1 {
fmt.Printf("key is: %d - value is: %f\n", key, value)
} // 读取 key
for key := range map1 {
fmt.Printf("key is: %d\n", key)
} // 读取 value
for _, value := range map1 {
fmt.Printf("value is: %f\n", value)
}
}
查看运行结果:
 
十五、集合
1.定义 Map
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
 
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)
 
实例如下:
package main

import "fmt"

func main() {
var countryCapitalMap map[string]string /*创建集合 */
countryCapitalMap = make(map[string]string) /* map插入key - value对,各个国家对应的首都 */
countryCapitalMap["France"] = "巴黎"
countryCapitalMap["Italy"] = "罗马"
countryCapitalMap["Japan"] = "东京"
countryCapitalMap["India "] = "新德里" /*使用键输出地图值 */
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap[country])
} /*查看元素在集合中是否存在 */
capital, ok := countryCapitalMap["American"] /*如果确定是真实的,则存在,否则不存在 */
/*fmt.Println(capital) */
/*fmt.Println(ok) */
if ok {
fmt.Println("American 的首都是", capital)
} else {
fmt.Println("American 的首都不存在")
}
}
查看运行结果:
2.delete() 函数
delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。实例如下:
package main

import "fmt"

func main() {
//2.delete() 函数
/* 创建map */
countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome", "Japan": "Tokyo", "India": "New delhi"} 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 语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。
递归函数对于解决数学上的问题是非常有用的,就像计算阶乘,生成斐波那契数列等
1.阶乘
package main

import "fmt"

func Factorial(n uint64) (result uint64) {
if n > 0 {
result = n * Factorial(n-1)
return result
}
return 1
} func main() {
//1.阶乘
var i int = 15
fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(uint64(i)))
}
查看运行结果:
2.斐波那契数列
package main

import "fmt"

func fibonacci(n int) int {
if n < 2 {
return n
}
return fibonacci(n-2) + fibonacci(n-1)
} func main() { //2.斐波那契数列
var i int
for i = 0; i < 10; i++ {
fmt.Printf("%d\t", fibonacci(i))
}
}
查看运行结果:
 
十七、数据类型转换
1.转换规则
类型转换用于将一种数据类型的变量转换为另外一种类型的变量。Go 语言类型转换基本格式如下:
type_name(expression)
 
2.实例
package main

import "fmt"

func main() {
var sum int = 17
var count int = 5
var mean float32 mean = float32(sum)/float32(count)
fmt.Printf("mean 的值为: %f\n",mean)
}
查看运行结果:
 
十八、接口
1.接口含义
Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
 
2.实例
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()
}
查看运行结果:
 
十九、错误处理
1.error简介
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
type error interface {
Error() string}
我们可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现}
在下面的例子中,我们在调用Sqrt的时候传递的一个负数,然后就得到了non-nil的error对象,将此对象与nil比较,结果为true,所以fmt.Println(fmt包在处理error时会调用Error方法)被调用,以输出错误,请看下面调用的示例代码:
result, err:= Sqrt(-1)

if err != nil {
fmt.Println(err)
}
2.实例
package main

import "fmt"

// 定义一个 DivideError 结构
type DivideError struct {
dividee int
divider int
} // 实现 `error` 接口
func (de *DivideError) Error() string {
strFormat := `
Cannot proceed, the divider is zero.
dividee: %d
divider: 0
`
return fmt.Sprintf(strFormat, de.dividee)
} // 定义 `int` 类型除法运算的函数
func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
if varDivider == 0 {
dData := DivideError{
dividee: varDividee,
divider: varDivider,
}
errorMsg = dData.Error()
return
} else {
return varDividee / varDivider, ""
} } func main() {
// 正常情况
if result, errorMsg := Divide(100, 10); errorMsg == "" {
fmt.Println("100/10 = ", result)
}
// 当除数为零的时候会返回错误信息
if _, errorMsg := Divide(100, 0); errorMsg != "" {
fmt.Println("errorMsg is: ", errorMsg)
}
}
查看运行结果:
 
二十、并发
1.并发介绍
Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。
语句:go f(x, y, z)
如:开启一个新的 goroutine:
f(x, y, z)
2.实例
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")
}
查看运行结果:
 
以下使用goland的IDE演示,包含总计的golang基础功能共20个章节
四、常量
 
 
 
一、go语言结构:
1.运行Hello World!
package main
 
import "fmt"
 
func main() {
fmt.Println("Hello World!")
}
查看运行结果:
2.语言结构:
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 输出到控制台。
6. 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
 
二、go基础语法:
1.行分隔符:
Println函数会在行末尾自动加上换行符
package main
 
import "fmt"
 
func main() {
fmt.Println("Hello World!")
fmt.Println("Println函数会在行末尾自动加上换行符")
}
查看运行结果:
2.注释:
单行注释以//开头,多行注释以 /* 开头,并以 */ 结尾
// 单行注释
/*
我说多行注释1
我说多行注释2
我说多行注释3
*/
3.标识符:
标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
以下是有效的标识符:
mahesh   kumar   abc   move_name   a_123
myname50   _temp   j   a23b9   retVal
以下是无效的标识符:
* 1ab(以数字开头)
* case(Go 语言的关键字)
* a+b(运算符是不允许的)
4.字符串连接:
Go 语言的字符串连接可以通过 + 实现:
import "fmt"
 
func main() {
fmt.Println("golang"+"python")
}
查看运行结果:
5.关键字:
下面列举了 Go 代码中会使用到的 25 个关键字或保留字:
break default func interface select
case defer go map struct 
chan else goto package switch
const fallthrough if range type
continue for import return var
6.格式化字符串:
// 常用的使用%d 表示整型数字,%s 表示字符串
package main
 
import "fmt"
 
func main() {
//fmt.Println("Hello World!")
//fmt.Println("Println函数会在行末尾自动加上换行符")
//fmt.Println("golang" + "python")
var today = "星期六"
var number = 6
fmt.Printf("今天是%s,今天在本周的排号为%d", today, number)
}
查看运行结果:
 
三、变量
1、申明一个变量值,变量类型,并初始化
(1)两种方式,方式1:使用var声明
package main
 
func main() {
var str string = "hello"
var num int = 123
println(str, num)
}
查看运行结果:
(2)使用:=声明
package main
 
func main() {
//var str string = "hello"
//var num int = 123
//println(str, num)
mystr := "very good"
mynum := 345
println(mystr, mynum)
 
}
查看运行结果:
2、申请变量未初始化,则会给默认值
数值类型初始值0
布尔类型为fasle
字符串为""
其他类型为nil
func main() {
//var str string = "hello"
//var num int = 123
//println(str, num)
 
//初始值0
var num1 int
fmt.Println("num1初始值为:", num1)
//初始值""
var str1 string
fmt.Println("str1初始值为:", str1)
//布尔类型为 false
var flag bool
fmt.Println("flag初始值为:", flag)
//其他类型为nil
var a *int
var b []int
var c map[string]int
var d chan int
var e func(string) int
var f error
fmt.Println("a,b,c,d,e,f的初始值分别为:", a, b, c, d, e, f)
}
查看运行结果:
3、根据值自行判定变量类型
package main
 
import (
"fmt"
"reflect"
)
 
func main() {
 
var str2 = "hello"
var num2 = 25
var flag2 = true
fmt.Println("str2的类型为:", reflect.TypeOf(str2))
fmt.Println("num2的类型为:", reflect.TypeOf(num2))
fmt.Println("flag2的类型为:", reflect.TypeOf(flag2))
}
查看运行结果:
4、多变量声明:
使用逗号隔开
package main
 
import "fmt"
 
func main() {
 
 
var str3, str4, str5 string = "hello", "World", "ok"
num3, num4, num5 := 2, 3, 4
fmt.Println(str3, str4, str5)
fmt.Println(num3, num4, num5)
 
}
查看运行结果:
5、引用类型变量
&可查看引用变量的地址
package main
 
import "fmt"
 
func main() {
 
var a1 = 10
var b1 = "ok"
fmt.Println("a1=", a1)
fmt.Println("b1=", b1)
fmt.Println("a1=", &a1)
fmt.Println("b1=", &b1)
}
查看运行结果:
 
四、常量
1.常量定义:
常量是一个简单值的标识符,在程序运行时,不会被修改的量,使用const修饰一个常量
package main
 
func main() {
const a string = "abc" //显示类型定义
const b = "abc" //隐示类型定义
const c, d = "o", "k"
println(a, b, c, d)
}
查看运行结果:
2. 常量还可以用作枚举:
并且常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过
package main
 
import "unsafe"
 
func main() {
//const a string = "abc" //显示类型定义
//const b = "abc" //隐示类型定义
//const c, d = "o", "k"
//println(a, b, c, d)
const (
Unknown = 0
Female = 1
Male = 2
)
 
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a) //16个字节,返回string结构体的字符与长度各8个字符相加
)
println(Unknown, Female, Male, a, b, c)
}
查看运行结果:
3.特殊常量iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
package main
 
func main() {
 
const (
a = iota
b
c
)
println(a, b, c)
}
查看运行结果:
package main
 
import "fmt"
 
func main() {
 
//println(a, b, c)
const (
a = iota //0
b //1
c //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a, b, c, d, e, f, g, h, i)
}
查看运行结果:
 
五、运算符
1.算数运算符:
package main
 
import "fmt"
 
func main() {
a := 1
b := 2
fmt.Println("a加b等于:", a+b)
fmt.Println("a减b等于:", a-b)
fmt.Println("a剩b等于:", a*b)
fmt.Println("a除b等于:", a/b)
fmt.Println("a除b后取余数等于:", a%b)
a++
fmt.Println("a++后的结果:", a)
b--
fmt.Println("b--后的结果:", b)
}
查看运行结果:
2.关系运算符
关系运算符主要有 =,!=,>,<,>=,<=共6种运算符
package main
 
import "fmt"
 
func main() {
 
var m int = 21
var n int = 10
if m == n {
fmt.Println("第一行返回:a等于b")
} else {
fmt.Println("第一行返回:a不等于b")
}
if m < n {
fmt.Println("第二行返回:a小于b")
} else {
fmt.Println("第二行返回:a不小于b")
}
if m > n {
fmt.Println("第三行返回:a大于b")
} else {
fmt.Println("第三行返回:a不大于b")
}
m, n = n, m //交换m,n的值
if m <= n {
fmt.Println("第四行返回:a小于等于b")
}
if m >= n {
fmt.Println("第四行返回:a不小于b")
}
}
查看运行结果:
3.逻辑运算符
主要有三种逻辑运算符:
&&:逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。
||:逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。
!:逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。
package main
 
import "fmt"
 
func main() {
 
var a bool = true
var b bool = false
if a && b {
fmt.Printf("第一行 - 条件为 true\n")
} else if a || b {
fmt.Printf("第一行 - 条件为 true\n")
}
a, b = b, a //修改a,b的值,对调
if a && b {
fmt.Printf("第二行 - 条件为 true\n")
} else {
fmt.Printf("第二行 - 条件为 false\n")
}
if !(a && b) {
fmt.Printf("第三行 - 条件为 true\n")
} else {
fmt.Printf("第三行 - 条件为 false\n")
}
 
}
查看运行结果:
4.位运算符
位运算符对整数在内存中的二进制位进行操作。
 &, |,  ^ ,<<,>>四种位运算方式
package main
 
import "fmt"
 
func main() {
 
var a uint = 60 /* 60 = 0011 1100 */
var b uint = 13 /* 13 = 0000 1101 */
var c uint = 0
 
c = 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)
 
}
查看运行结果:
5.赋值运算符
赋值符号为=,将一个表达式的值赋给一个左值,结合之前其他的型号的赋值运算符如下:
package main
 
import "fmt"
 
func main() {
 
var a int = 21
var c int
 
c = a
fmt.Printf("第 1 行 - = 运算符实例,c 值为 = %d\n", c)
 
c += a
fmt.Printf("第 2 行 - += 运算符实例,c 值为 = %d\n", c)
 
c -= a
fmt.Printf("第 3 行 - -= 运算符实例,c 值为 = %d\n", c)
 
c *= a
fmt.Printf("第 4 行 - *= 运算符实例,c 值为 = %d\n", c)
 
c /= a
fmt.Printf("第 5 行 - /= 运算符实例,c 值为 = %d\n", c)
 
c = 200
 
c <<= 2
fmt.Printf("第 6行 - <<= 运算符实例,c 值为 = %d\n", c)
 
c >>= 2
fmt.Printf("第 7 行 - >>= 运算符实例,c 值为 = %d\n", c)
 
c &= 2
fmt.Printf("第 8 行 - &= 运算符实例,c 值为 = %d\n", c)
 
c ^= 2
fmt.Printf("第 9 行 - ^= 运算符实例,c 值为 = %d\n", c)
 
c |= 2
fmt.Printf("第 10 行 - |= 运算符实例,c 值为 = %d\n", c)
}
查看运行结果:
 
六、条件语句
1.if else语句:
package main
 
import "fmt"
 
func main() {
//if else语句
age := 18
if age < 5 {
fmt.Println("你的age为:", age, ",你太小了无法进入")
} else if age < 18 {
fmt.Println("你的age为:", age, ",你虽然不小了,但是仍然未满18,无法进入")
} else {
fmt.Println("你的age为:", age, ",你已满18岁,可以进入")
}
}
查看运行结果:
2.if嵌套语句
计算可以数字a在0-100内,且是否可以被5整除
package main
 
import "fmt"
 
func main() {
 
a := 100
//if嵌套
if a <= 100 {
fmt.Println("a的值符合条件1:在0~100内,为:", a)
if a%5 == 0 {
fmt.Println("a的值符合条件2:可以被5整除,为:", a)
} else {
fmt.Println("a的值不符合条件2:不可以被5整除,为:", a)
 
}
} else {
fmt.Println("a的值不符合条件1:非在0~100内,为:", a)
 
}
}
查看运行结果:
3.switch语句
(1)switch+case语句:
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。
witch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case
package main
 
import "fmt"
 
func main() {
 
//3.switch case语句
score := 75
var grade string
switch {
case score < 60:
grade = "C"
case score >= 60 && score < 80:
grade = "B"
case score >= 80:
grade = "A"
}
fmt.Println(grade)
 
}
查看运行结果:
(2)switch+case+fallthrough
使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。
package main
 
import "fmt"
 
func main() {
 
score := 95
var grade string
switch {
case score < 60:
grade = "C"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 60 && score < 80:
grade = "B"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 80:
grade = "A"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
}
fmt.Println(grade)
}
查看运行结果:
(3)switch+default:
defalut如果放在哪里是会最后执行
package main
 
import "fmt"
 
func main() {
 
score := 200
var grade string
switch {
default:
grade = "Nothing"
fmt.Printf("你的成绩为%d,并不合法,最终grade为%s", score, grade)
case score < 60:
grade = "C"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 60 && score < 80:
grade = "B"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
case score >= 80 && score <= 100:
grade = "A"
fallthrough
case false:
fmt.Println("使用fallthrough语句跳入到了下一步打印此句,因为您的成绩为:", grade)
}
 
}
查看运行结果:
4.select语句
select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。
select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。
package main
 
import "fmt"
 
func main() {
 
var c1, c2, c3 chan int
var i1, i2 int
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
default:
fmt.Printf("no communication\n")
}
 
}
查看运行结果:
 
七、循环
1.for循环
(1)for condition {}
package main
 
import "fmt"
 
func main() {
//1.for condition语句
sum := 0
for i := 1; i <= 10; i++ {
sum += i
}
fmt.Println(sum) //累加1~10
}
查看运行结果:
(2)for init {}
package main
 
import "fmt"
 
func main() {
 
Strings := []string{"google", "golang"}
for m, n := range Strings {
fmt.Println(m, n)
}
}
查看运行结果:
 
2.循环嵌套
package main
 
import "fmt"
 
func main() {
 
 
//2.循环嵌套:找到1-30内的素数
var i, j int
for i = 2; i < 30; i++ {
for j = 2; j <= i/j; j++ {
if i%j == 0 {
break
}
}
if j > (i / j) {
fmt.Println(i, "是一个素数")
}
}
}
查看运行结果:
 
3.break语句
Go 语言中 break 语句用于以下两方面:
(1) 用于循环语句中跳出循环,并开始执行循环之后的语句。
//3.1 break跳出循环
var a int = 10
for a < 20 {
fmt.Println("a的值:", a)
a++
if a == 15 {
break
}
}
}
查看运行结果:
(2) break 在 switch(开关语句)中在执行一条 case 后跳出语句的作用。(此break会隐藏)
(3)在多重循环中,可以用标号 label 标出想 break 的循环。
package main
 
import "fmt"
 
func main() {
 
//3.2 break label标出想break的循环
// 不使用标记
fmt.Println("---- break ----")
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
break
}
}
 
// 使用标记
fmt.Println("---- break label ----")
re:
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
break re
}
}
 
}
查看运行结果:
 
4.continue 语句
Go 语言的 continue 语句 有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。
(1)for 循环中,执行 continue 语句会触发 for 增量语句的执行。
package main
 
import "fmt"
 
func main() {
 
//4.1 continue语句,不是跳出循环,而是跳过当前循环执行下一次循环语句
a := 10
for a < 20 {
a++
if a == 15 {
continue
}
fmt.Println("a的值为:", a)
}
 
}
查看运行结果:
(2)在多重循环中,可以用标号 label 标出想 continue 的循环。
package main
 
import "fmt"
 
func main() {
 
//4.2 使用continue+label标出想 continue 的循环
// 不使用标记
fmt.Println("---- continue ---- ")
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
continue
}
}
 
// 使用标记
fmt.Println("---- continue label ----")
re:
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
continue re
}
}
 
}
查看运行结果:
 
5.goto 语句
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
package main
 
import "fmt"
 
func main() {
 
//5.goto语句可以无条件地转移到过程中指定的行
/* 定义局部变量 */
var a int = 10
 
/* 循环 */
LOOP:
for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LOOP
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
}
查看运行结果:
 
八、函数
1.函数定义与调用
Go 语言最少有个 main() 函数。
你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。
函数定义解析:
* func:函数由 func 开始声明
* function_name:函数名称,参数列表和返回值类型构成了函数签名。
* parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
* return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
* 函数体:函数定义的代码集合。
package main
 
import "fmt"
 
func main() {
var a int = 98
var b int = 99
var c int = max(a, b)
fmt.Println("a,b两个数的最大值为:", c)
}
 
func max(num1, num2 int) int {
/* 声明局部变量 */
var result int
 
if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
查看运行结果:
 
2.函数返回多个值
package main
 
import "fmt"
 
func main() {
 
x := "hello"
y := "world"
fmt.Println("交换前的x与y分别为:", x, y)
x, y = swap(x, y)
fmt.Println("交换后的x与y分别为:", x, y)
}
 
func swap(x, y string) (string, string) {
x, y = y, x
return x, y
}
查看运行结果:
 
3.值传递与引用传递
(1)值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
package main
 
import (
"fmt"
)
 
func main() {
 
x := "hello"
y := "world"
fmt.Println("交换前的x与y分别为:", x, y)
swap(x, y)
fmt.Println("交换后的x与y分别为:", x, y)
}
 
//值传递
func swap(x, y string) string {
var temp string
temp = x
x = y
y = temp
return temp
}
 
查看运行结果:
(2)引用传递:引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
package main
 
import (
"fmt"
)
 
func main() {
//var a int = 98
//var b int = 99
//var c int = max(a, b)
//fmt.Println("a,b两个数的最大值为:", c)
 
x := "hello"
y := "world"
fmt.Println("交换前的x与y分别为:", x, y)
swap(&x, &y)
fmt.Println("交换后的x与y分别为:", x, y)
}
 
//func max(num1, num2 int) int {
// /* 声明局部变量 */
// var result int
//
// if num1 > num2 {
// result = num1
// } else {
// result = num2
// }
// return result
//}
 
////值传递
//func swap(x, y string) string {
// var temp string
// temp = x
// x = y
// y = temp
// return temp
//}
 
//引用传递
func swap(x, y *string) string {
var temp string
temp = *x
*x = *y
*y = temp
return temp
}
查看运行结果:
4.函数作为另外一个函数的实参(进阶ToDo)
5.闭包(进阶ToDo)
6.方法(进阶ToDo)
 
 
九、变量作用域
1.局部变量:
* 函数内定义的变量称为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
package main
 
import "fmt"
 
func main() {
/* 声明局部变量 */
var a, b, c int
 
/* 初始化参数 */
a = 10
b = 20
c = a + b
 
fmt.Printf("结果: a = %d, b = %d and c = %d\n", a, b, c)
}
查看运行结果:
 
2.全局变量
* 函数外定义的变量称为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用
package main
 
import "fmt"
 
/* 声明全局变量 */
var g int
 
func main() {
 
/* 声明局部变量 */
var a, b int
 
/* 初始化参数 */
a = 10
b = 20
g = a + b
 
fmt.Printf("结果: a = %d, b = %d and g = %d\n", a, b, g)
}
查看运行结果:
 
3.形式参数
形式参数会作为函数的局部变量来使用。实例如下:
package main
 
import "fmt"
 
///* 声明全局变量 */
//var g int
 
/* 声明全局变量 */
var a int = 20
 
func main() {
 
/* main 函数中声明局部变量 */
var a int = 10
var b int = 20
var c int = 0
 
fmt.Printf("main()函数中 a = %d\n", a)
c = sum(a, b)
fmt.Printf("main()函数中 c = %d\n", c)
}
 
/* 函数定义-两数相加 */
func sum(a, b int) int {
fmt.Printf("sum() 函数中 a = %d\n", a)
fmt.Printf("sum() 函数中 b = %d\n", b)
 
return a + b
}
查看运行结果:
 
4.初始化局部和全局变量
不同类型的局部和全局变量的默认值为:
int为0
float32为0
pointer为nil
 
十、数组
1.声明数组
例如以下定义了数组 balance 长度为 10 类型为 float32:
var balance [10] float32
 
2.初始化数组
package main
 
import "fmt"
 
func main() {
//1.初始化数组
balance1 := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
fmt.Println(balance1)
//如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度:
balance2 := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
fmt.Println(balance2)
}
查看运行结果:
 
3.访问数组元素
package main
 
import "fmt"
 
func main() {
 
//3.访问列表元素,通过for循环方式遍历
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])
}
}
查看运行结果:
 
4.多维数组(进阶ToDo)
5.向函数传递数组(进阶ToDo)
 
十一、指针
1.指针的使用
一个指针变量指向了一个值的内存地址。
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)
}
查看运行结果:
 
2.空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr。
package main
 
import "fmt"
 
func main() {
 
//空指针
var ptr *int
fmt.Printf("ptr 的值为 : %x\n", ptr)
}
查看运行结果:
 
3.指针数组(进阶ToDo)
4.指向指针的指针(进阶ToDo)
5.指针作为函数参数(进阶ToDo)
 
 
十二、结构体
1.定义结构体
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。
package main
 
import "fmt"
 
//定义结构体
type Books struct {
title string
author string
subject string
bookId int
}
 
func main() {
// 创建一个新的结构体
fmt.Println(Books{"Go 语言", "mr.white", "Go语言教程", 100001})
 
// 也可以使用 key => value 格式
fmt.Println(Books{title: "Go 语言", author: "mr.white", subject: "Go语言教程", bookId: 100002})
 
// 忽略的字段为 0 或 空
fmt.Println(Books{title: "Go 语言", author: "mr.white"})
}
查看运行结果:
 
2.访问结构体成员
如果要访问结构体成员,需要使用点号 . 操作符。
package main
 
import "fmt"
 
//定义结构体
type Books struct {
title string
author string
subject string
bookId int
}
 
func main() {
 
/* book 1 描述 */
Book1.title = "Go 语言"
Book1.author = "mr.white"
Book1.subject = "Go 语言教程"
Book1.bookId = 100001
 
/* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "mr.white"
Book2.subject = "Python 语言教程"
Book2.bookId = 100002
 
/* 打印 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.bookId)
 
/* 打印 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.bookId)
}
查看运行结果:
 
3.结构体作为函数参数(进阶ToDo)
4.结构体指针(进阶ToDo)
 
十三、切片
1.定义/切片初始化
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
package main
 
import "fmt"
 
func main() {
//1.直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3。
s := []int{1, 2, 3}
fmt.Println("切片s:", s)
//初始化切片 s1,是数组 s 的引用。
s1 := s[:]
fmt.Println("切片s1:", s1)
//初始化切片 s2,是从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。
s2 := s[1:3]
fmt.Println("切片s2:", s2)
//使用make初始化切片
s3 := make([]int, 3)
fmt.Println("切片s3:", s3)
}
查看运行结果:
 
2.len() 和 cap() 函数
len() 方法获取切片的长度
cap()方法 可以测量切片最长可以达到多少
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//2调用printSlice方法获取切片的长度与容量
var numbers = make([]int, 3, 5)
printSlice(numbers)
}
查看运行结果:
 
3.空(nil)切片
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//3.空切片
var numbers []int
printSlice(numbers)
if numbers == nil {
fmt.Println("切片是空的呢")
}
}
查看运行结果:
 
6.切片截取
可以通过设置下限及上限来设置截取切片 [lower-bound:upper-bound],实例如下:
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//切片截取举例
/* 创建切片 */
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
printSlice(numbers)
 
/* 打印原始切片 */
fmt.Println("numbers ==", numbers)
 
/* 打印子切片从索引1(包含) 到索引4(不包含)*/
fmt.Println("numbers[1:4] ==", numbers[1:4])
 
/* 默认下限为 0*/
fmt.Println("numbers[:3] ==", numbers[:3])
 
/* 默认上限为 len(s)*/
fmt.Println("numbers[4:] ==", numbers[4:])
 
numbers1 := make([]int, 0, 5)
printSlice(numbers1)
 
/* 打印子切片从索引 0(包含) 到索引 2(不包含) */
number2 := numbers[:2]
printSlice(number2)
 
/* 打印子切片从索引 2(包含) 到索引 5(不包含) */
number3 := numbers[2:5]
printSlice(number3)
}
查看运行结果:
 
7.append() 和 copy() 函数
如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。
下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//5.append() 和 copy() 函数
var numbers []int
printSlice(numbers)
 
/* 允许追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers)
 
/* 向切片添加一个元素 */
numbers = append(numbers, 1)
printSlice(numbers)
 
/* 同时添加多个元素 */
numbers = append(numbers, 2,3,4)
printSlice(numbers)
 
/* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2)
 
/* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
}
查看运行结果:
 
十四、范围(Range)
1.range的最用
range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环
 
2.举例说明
package main
 
import "fmt"
 
func main() {
map1 := make(map[int]float32)
map1[1] = 1.0
map1[2] = 2.0
map1[3] = 3.0
map1[4] = 4.0
 
// 读取 key 和 value
for key, value := range map1 {
fmt.Printf("key is: %d - value is: %f\n", key, value)
}
 
// 读取 key
for key := range map1 {
fmt.Printf("key is: %d\n", key)
}
 
// 读取 value
for _, value := range map1 {
fmt.Printf("value is: %f\n", value)
}
}
查看运行结果:
 
十五、集合
1.定义 Map
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
 
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)
 
实例如下:
package main
 
import "fmt"
 
func main() {
var countryCapitalMap map[string]string /*创建集合 */
countryCapitalMap = make(map[string]string)
 
/* map插入key - value对,各个国家对应的首都 */
countryCapitalMap["France"] = "巴黎"
countryCapitalMap["Italy"] = "罗马"
countryCapitalMap["Japan"] = "东京"
countryCapitalMap["India "] = "新德里"
 
/*使用键输出地图值 */
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap[country])
}
 
/*查看元素在集合中是否存在 */
capital, ok := countryCapitalMap["American"] /*如果确定是真实的,则存在,否则不存在 */
/*fmt.Println(capital) */
/*fmt.Println(ok) */
if ok {
fmt.Println("American 的首都是", capital)
} else {
fmt.Println("American 的首都不存在")
}
}
查看运行结果:
 
2.delete() 函数
delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。实例如下:
package main
 
import "fmt"
 
func main() {
//2.delete() 函数
/* 创建map */
countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome", "Japan": "Tokyo", "India": "New delhi"}
 
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 语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。
递归函数对于解决数学上的问题是非常有用的,就像计算阶乘,生成斐波那契数列等
 
1.阶乘
package main
 
import "fmt"
 
func Factorial(n uint64) (result uint64) {
if n > 0 {
result = n * Factorial(n-1)
return result
}
return 1
}
 
func main() {
//1.阶乘
var i int = 15
fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(uint64(i)))
}
查看运行结果:
 
2.斐波那契数列
package main
 
import "fmt"
 
func fibonacci(n int) int {
if n < 2 {
return n
}
return fibonacci(n-2) + fibonacci(n-1)
}
 
func main() {
 
//2.斐波那契数列
var i int
for i = 0; i < 10; i++ {
fmt.Printf("%d\t", fibonacci(i))
}
}
查看运行结果:
 
十七、数据类型转换
1.转换规则
类型转换用于将一种数据类型的变量转换为另外一种类型的变量。Go 语言类型转换基本格式如下:
type_name(expression)
 
2.实例
package main
 
import "fmt"
 
func main() {
var sum int = 17
var count int = 5
var mean float32
 
mean = float32(sum)/float32(count)
fmt.Printf("mean 的值为: %f\n",mean)
}
查看运行结果:
 
十八、接口
1.接口含义
Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
 
2.实例
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()
}
查看运行结果:
 
十九、错误处理
1.error简介
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
type error interface {
Error() string}
我们可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现}
在下面的例子中,我们在调用Sqrt的时候传递的一个负数,然后就得到了non-nil的error对象,将此对象与nil比较,结果为true,所以fmt.Println(fmt包在处理error时会调用Error方法)被调用,以输出错误,请看下面调用的示例代码:
result, err:= Sqrt(-1)
 
if err != nil {
fmt.Println(err)
}
 
2.实例
package main
 
import "fmt"
 
// 定义一个 DivideError 结构
type DivideError struct {
dividee int
divider int
}
 
// 实现 `error` 接口
func (de *DivideError) Error() string {
strFormat := `
Cannot proceed, the divider is zero.
dividee: %d
divider: 0
`
return fmt.Sprintf(strFormat, de.dividee)
}
 
// 定义 `int` 类型除法运算的函数
func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
if varDivider == 0 {
dData := DivideError{
dividee: varDividee,
divider: varDivider,
}
errorMsg = dData.Error()
return
} else {
return varDividee / varDivider, ""
}
 
}
 
func main() {
// 正常情况
if result, errorMsg := Divide(100, 10); errorMsg == "" {
fmt.Println("100/10 = ", result)
}
// 当除数为零的时候会返回错误信息
if _, errorMsg := Divide(100, 0); errorMsg != "" {
fmt.Println("errorMsg is: ", errorMsg)
}
}
查看运行结果:
 
二十、并发
1.并发介绍
Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。
语句:go f(x, y, z)
如:开启一个新的 goroutine:
f(x, y, z)
 
2.实例
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")
}
查看运行结果;
 

Golang基础教程的更多相关文章

  1. golang基础教程——字符串篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第6篇文章,这篇主要和大家聊聊golang当中的字符串的使用. 字符串定义 golang当中的字符串本质是只读的字符 ...

  2. Golang基础教程——map使用篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第7篇文章,我们来聊聊golang当中map的用法. map这个数据结构我们经常使用,存储的是key-value的键 ...

  3. matlab基础教程——根据Andrew Ng的machine learning整理

    matlab基础教程--根据Andrew Ng的machine learning整理 基本运算 算数运算 逻辑运算 格式化输出 小数位全局修改 向量和矩阵运算 矩阵操作 申明一个矩阵或向量 快速建立一 ...

  4. <<Bootstrap基础教程>> 新书出手,有心栽花花不开,无心插柳柳成荫

    并非闲的蛋疼,做技术也经常喜欢蛋疼,纠结于各种技术,各种需求变更,还有一个很苦恼的就是UI总是那么不尽人意.前不久自己开源了自己做了多年的仓储项目(开源地址:https://github.com/he ...

  5. Memcache教程 Memcache零基础教程

    Memcache是什么 Memcache是danga.com的一个项目,来分担数据库的压力. 它可以应对任意多个连接,使用非阻塞的网络IO.由于它的工作机制是在内存中开辟一块空间,然后建立一个Hash ...

  6. Selenium IDE 基础教程

    Selenium IDE 基础教程 1.下载安装     a 在火狐浏览其中搜索附件组件,查找 Selenium IDE     b 下载安装,然后重启firefox 2.界面讲解      在菜单- ...

  7. html快速入门(基础教程+资源推荐)

    1.html究竟是什么? 从字面上理解,html是超文本标记语言hyper text mark-up language的首字母缩写,指的是一种通用web页面描述语言,是用来描述我们打开浏览器就能看到的 ...

  8. 转发-UI基础教程 – 原生App切图的那些事儿

    UI基础教程 – 原生App切图的那些事儿 转发:http://www.shejidaren.com/app-ui-cut-and-slice.html 移动APP切图是UI设计必须学会的一项技能,切 ...

  9. 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...

随机推荐

  1. GDB的简单使用一

    GDB的简单使用一 一.概念 二.GDB的基本使用方法一 调试前预备知识 获取进程的内核转储 启动gdb调试 1.启动 2.设置断点 3.运行程序 4.显示栈帧 5.显示变量 6.显示寄存器 7.单步 ...

  2. 《HALCON数字图像处理》第四章笔记

    目录 第四章 HALCON数据结构 HALCON Image图像 图像通道 HALCON Region区域 Region的初步介绍 Region的点与线 Region的行程 Region的区域特征 H ...

  3. SQL Server 2008~2019版本序列号/密钥/激活码 汇总

    SQL Server 2019 Enterprise:HMWJ3-KY3J2-NMVD7-KG4JR-X2G8G Strandard:PMBDC-FXVM3-T777P-N4FY8-PKFF4 SQL ...

  4. rpm构建流程学习总结

    rpm构建流程 学习链接: b站马哥: https://www.bilibili.com/video/BV1ai4y1N7gp RedHat: https://access.redhat.com/do ...

  5. iOS全埋点解决方案-APP和H5打通

    前言 ​ 所谓的 APP 和 H5 打通,是指 H5 集成 JavaScript 数据采集 SDK 后,H5 触发的事件不直接同步给服务器,而是先发给 APP 端的数据采集 SDK,经过 APP 端数 ...

  6. 5G的发布加快了智慧城市/三维物联网等行业的发展

    最近很多人发现自己的5G手机突然没了5G信号,难道是美国搞的鬼? 不不不,这其实是因为5G的NSA基站被撤站了,官方已经做了部署,要大力推进SA网络建设.所以之前支持NSA模式的5G手机,现在都成了4 ...

  7. Python-安装lmdb失败-解决方法

    使用pip install lmdb 时报错 ERROR: Command errored out with exit status 1: python setup.py egg_info Check ...

  8. 一篇文章带你深入浅出Vuex

    在写Vuex之前,我们先用一个简单的例子来实现一个小demo 大家都知道Vue的父传子用在很多场景,比如像这样: 父组件: <template> <div id="app& ...

  9. zabbix监控钉钉报警

    1. bash脚本 #!/bin/bash to=$1 subject=$2 text=$3 #此处的 xxxxx 就是刚刚复制存留的 api 接口地址. curl -i -X POST \ 'htt ...

  10. RPA应用场景-信用卡交易争议后续流程

    RPA应用场景-信用卡交易争议后续流程 场景概述 信用卡交易争议后续流程 所涉系统名称 客服系统,邮件 人工操作(时间/次) 4小时 所涉人工数量20操作频率 不定时 场景流程 1.RPA自动接收客户 ...