博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【GO 开发系列 -- 基础】Go 基础简介
阅读量:357 次
发布时间:2019-03-04

本文共 14606 字,大约阅读时间需要 48 分钟。

【GO 开发系列 -- 基础】Go 基础简介

【1】Golang 言简介

【1.1】GO 语言的定义

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。

【1.2】GO 语言的特点

Go言既拥有态编译语言的安全和性能,又拥有动态语开发维护的高效率;

态编译语言 :态编译语是在编译时变量的数据型即可定的言,多数静态类言要求在使用量之前必须声明数据型;

动态语言 : 动态语言是在时确定数据型的言,量使用之前不需要型声明,通常量的型是被赋值的那个型;

  • 1. 包含与 C 似的法、控制结构,基础数据,调用参数传值,指针等;
  • 2. 引入包的概念,Go言的每一个文件都属于一个包,不能独存在;
  • 3. 垃圾回收机制,内存自回收;
  • 4. 天然并发;
  •   (1) 从面支持并;
  •   (2) goroutine,级线程,高效利用多核;
  •   (3) 基于 并发模型实现;
  • 5. 管道通信机制,通管道实现不同的 goroute 之的通信;
  • 6. 函数可以返回多个值;

【2】Golang 语言基本语法示例

【2.1】变量

golang 中标识符的使用

package mainimport "fmt"//golang 中标识符的使用func main() {	//Golang中严格区分大小写	//golang 中 认为 num 和 Num是不同的变量	var num int = 10	var Num int = 20	//输出: num=10 Num=20	fmt.Printf("num=%v Num=%v\n", num, Num)	//标识符不能包含空格	//var ab c int = 30	//_ 是空标志符,用于占用	// var _ int = 40 //error	// fmt.Println(_)	var int int = 90	//输出: 90	fmt.Println(int)}

golang 中变量的使用

package mainimport "fmt"//golang 中变量的使用func main() {	//golang的变量使用方式1	//第一种:指定变量类型,声明后若不赋值,使用默认值	// int 的默认值是0 , 其它数据类型的默认值后面马上介绍	var i int	//输出: i= 0	fmt.Println("i=", i)	//第二种:根据值自行判定变量类型(类型推导)	var num = 10.11	//输出: num= 10.11	fmt.Println("num=", num)	//第三种:省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误	//下面的方式等价 var name string   name = "tom"	// := 的 :不能省略,否则错误	name := "tom"	//输出: name= tom	fmt.Println("name=", name)}
package mainimport "fmt"//定义全局变量var n1 = 100var n2 = 200var name = "jack"//上面的声明方式,也可以改成一次性声明var (	n3    = 300	n4    = 900	name2 = "mary")func main() {	//该案例演示golang如何一次性声明多个变量	var n5, n6, n7 int	//输出: n5= 0 n6= 0 n7= 0	fmt.Println("n5=", n5, "n6=", n6, "n7=", n7)	//一次性声明多个变量的方式2	var n8, name3, n9 = 100, "tom", 888	//输出: n8= 100 name3= tom n9= 888	fmt.Println("n8=", n8, "name3=", name3, "n9=", n9)	//一次性声明多个变量的方式3, 同样可以使用类型推导	n10, name4, n11 := 100, "tom~", 888	//输出: n10= 100 name4= tom~ n11= 888	fmt.Println("n10=", n10, "name4=", name4, "n11=", n11)	//输出全局变量	//输出: n1= 100 name= jack n2= 200	fmt.Println("n1=", n1, "name=", name, "n2=", n2)	//输出: n3= 300 name2= mary n4= 900	fmt.Println("n3=", n3, "name2=", name2, "n4=", n4)}
package mainimport (	"fmt"	//为了使用utils.go文件的变量或者函数,我们需要先引入该model包	"GO_LEARN_CODE/chapter03/demo04/model")//变量使用的注意事项func main() {	//该区域的数据值可以在同一类型范围内不断变化	var i int = 10	i = 30	i = 50	//输出: i= 50	fmt.Println("i=", i)	//i = 1.2 //int ,原因是不能改变数据类型	//变量在同一个作用域(在一个函数或者在代码块)内不能重名	//var i int = 59	//i := 99	//我们使用 utils.go 的 heroName 包名.标志符	//输出: 宋江	fmt.Println(model.HeroName)}package model//定义了一个变量var HeroName string = "宋江"

golang 中整数类型使用

package main// import "fmt"// import "unsafe"import (	"fmt"	"unsafe")// golang 中整数类型使用func main() {	var i int = 1	//输出: i= 1	fmt.Println("i=", i)	//测试一下 int8 的范围 -128~127,	//其它的 int16, int32, int64, 类推 ...	var j int8 = 127	//输出: j= 127	fmt.Println("j=", j)	//测试一下 uint8 的范围(0-255),其它的 uint16, uint32, uint64 类推即可	var k uint16 = 255	// 输出: k= 255	fmt.Println("k=", k)	//int , uint , rune , byte的使用	var a int = 8900	//输出: a= 8900	fmt.Println("a=", a)	var b uint = 1	var c byte = 255	//输出: b= 1 c= 255	fmt.Println("b=", b, "c=", c)	//整型的使用细节	var n1 = 100 // n1 是什么类型	//这里我们给介绍一下如何查看某个变量的数据类型	//fmt.Printf() 可以用于做格式化输出。	//输出: n1 的 类型 int	fmt.Printf("n1 的 类型 %T \n", n1)	//如何在程序查看某个变量的占用字节大小和数据类型 (使用较多)	var n2 int64 = 10	//unsafe.Sizeof(n1) 是 unsafe 包的一个函数,可以返回 n1 变量占用的字节数	//输出: n2 的 类型 int64  n2占用的字节数是 8	fmt.Printf("n2 的 类型 %T  n2占用的字节数是 %d ", n2, unsafe.Sizeof(n2))}

golang 中小数类型使用

package mainimport (	"fmt"	"unsafe")//golang 中小数类型使用func main() {	var price float32 = 89.12	//输出: price= 89.12	fmt.Println("price=", price)	var num1 float32 = -0.00089	var num2 float64 = -7809656.09	//输出: num1= -0.00089 num2= -7.80965609e+06	fmt.Println("num1=", num1, "num2=", num2)	//尾数部分可能丢失,造成精度损失。 -123.0000901	var num3 float32 = -123.0000901	var num4 float64 = -123.0000901	num3= -123.00009 num4= -123.0000901	fmt.Println("num3=", num3, "num4=", num4)	//Golang 的浮点型默认声明为 float64 类型	var num5 = 1.1	//输出: num5的数据类型是 float64	fmt.Printf("num5的数据类型是 %T \n", num5)	//十进制数形式:如:5.12       .512   (必须有小数点)	num6 := 5.12	num7 := .123 //=> 0.123	//输出: num6= 5.12 num7= 0.123	fmt.Println("num6=", num6, "num7=", num7)	//科学计数法形式	num8 := 5.1234e2   // 5.1234 * 10的2次方	num9 := 5.1234E2   // 5.1234 * 10的2次方	num10 := 5.1234E-2 // 5.1234 / 10的2次方 0.051234	//输出: num8= 512.34 num9= 512.34 num10= 0.051234	fmt.Println("num8=", num8, "num9=", num9, "num10=", num10)	/**	 * byte 等同于 int8,常用来处理 ascii 字符	 * rune 等同于 int32,常用来处理 unicode 或 utf-8 字符	 */	var c1 rune = '北'	//输出: c1= 21271 4	fmt.Println("c1=", c1, unsafe.Sizeof(c1))}

golang 中基本数据类型的转换

package mainimport (	"fmt")// golang 中基本数据类型的转换func main() {	var i int32 = 100	//希望将 i => float	var n1 float32 = float32(i)	var n2 int8 = int8(i)	var n3 int64 = int64(i) //低精度->高精度	//输出: i=100 n1=100 n2=100 n3=100	fmt.Printf("i=%v n1=%v n2=%v n3=%v \n", i, n1, n2, n3)	//被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化	//输出: i type is int32	fmt.Printf("i type is %T\n", i) // int32	//在转换中,比如将 int64  转成 int8 【-128---127】 ,编译时不会报错,	//只是转换的结果是按溢出处理,和我们希望的结果不一样	var num1 int64 = 999999	var num2 int8 = int8(num1)	//输出: num2= 63	fmt.Println("num2=", num2)}

golang 中指针类型使用

package mainimport (	"fmt")//golang 中指针类型func main() {	//基本数据类型在内存布局	var i int = 10	// i 的地址是什么,&i	//输出: i的地址= 0xc00004e080	fmt.Println("i的地址=", &i)	//下面的 var ptr *int = &i	//1. ptr 是一个指针变量	//2. ptr 的类型 *int	//3. ptr 本身的值&i	var ptr *int = &i	//输出: ptr=0xc00004e080	fmt.Printf("ptr=%v\n", ptr)	//输出: ptr 的地址=0xc000076020ptr 指向的值=10	fmt.Printf("ptr 的地址=%v", &ptr)	fmt.Printf("ptr 指向的值=%v", *ptr)}

golang 中字符类型使用

package mainimport (	"fmt")//golang 中字符类型使用func main() {	var c1 byte = 'a'	var c2 byte = '0' //字符的0	//当我们直接输出byte值,就是输出了的对应的字符的码值	// 'a' ==>	//输出: c1= 97 c2= 48	fmt.Println("c1=", c1)	fmt.Println("c2=", c2)	//如果我们希望输出对应字符,需要使用格式化输出	//输出: c1=a c2=0	fmt.Printf("c1=%c c2=%c\n", c1, c2)	//var c3 byte = '北' //overflow溢出	var c3 int = '北' //overflow溢出	//输出: c3=北 c3对应码值=21271	fmt.Printf("c3=%c c3对应码值=%d\n", c3, c3)	//可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode 字符	var c4 int = 22269 // 22269 -> '国' 120->'x'	//输出: c4=国	fmt.Printf("c4=%c\n", c4)	//字符类型是可以进行运算的,相当于一个整数,运输时是按照码值运行	var n1 = 10 + 'a' //  10 + 97 = 107	//输出: n1= 107	fmt.Println("n1=", n1)}

 

golang 中 bool 类型使用

package mainimport (	"fmt"	"unsafe")//golang 中 bool 类型使用func main() {	var b = false	//输出: b= false	fmt.Println("b=", b)	//输出: b 的占用空间 = 1	//注意事项	//1. bool类型占用存储空间是1个字节	fmt.Println("b 的占用空间 =", unsafe.Sizeof(b))	//2. bool类型只能取true或者false}

golang 中 string 类型使用

package mainimport (	"fmt")//golang 中 string 类型使用func main() {	//string 的基本使用	var address string = "北京长城 110 hello world!"	//输出: 北京长城 110 hello world!	fmt.Println(address)	//字符串一旦赋值了,字符串就不能修改了:在Go中字符串是不可变的	//var str = "hello"	//str[0] = 'a' //这里就不能去修改str的内容,即go中的字符串是不可变的。	//字符串的两种表示形式	//(1) 双引号, 会识别转义字符;	//(2) 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击, 输出源代码等效果	str2 := "abc\nabc"	/**	 * 输出:	 * abc	 * abc	 */	fmt.Println(str2)	//使用的反引号 ``	str3 := ` 	package main	import (		"fmt"		"unsafe"	)		//演示golang中bool类型使用	func main() {		var b = false		fmt.Println("b=", b)		//注意事项		//1. bool类型占用存储空间是1个字节		fmt.Println("b 的占用空间 =", unsafe.Sizeof(b) )		//2. bool类型只能取true或者false			}	`	fmt.Println(str3)	//字符串拼接方式	var str = "hello " + "world"	str += " haha!"	fmt.Println(str)	//当一个拼接的操作很长时,怎么办,可以分行写,但是注意,需要将+保留在上一行.	str4 := "hello " + "world" + "hello " + "world" + "hello " +		"world" + "hello " + "world" + "hello " + "world" +		"hello " + "world"	fmt.Println(str4)	var a int          // 0	var b float32      // 0	var c float64      // 0	var isMarried bool // false	var name string    // ""	//这里的 %v 表示按照变量的值输出	//输出: a=0,b=0,c=0,isMarried=false name=	fmt.Printf("a=%d,b=%v,c=%v,isMarried=%v name=%v", a, b, c, isMarried, name)}

golang 中基本数据转成 string

package mainimport (	"fmt"	"strconv"	_ "unsafe")//golang 中基本数据转成 stringfunc main() {	var num1 int = 99	var num2 float64 = 23.456	var b bool = true	var myChar byte = 'h'	var str string //空的str	//使用第一种方式来转换 fmt.Sprintf 方法	//输出: str type string str="99"	str = fmt.Sprintf("%d", num1)	fmt.Printf("str type %T str=%q\n", str, str)	//输出: str type string str="23.456000"	str = fmt.Sprintf("%f", num2)	fmt.Printf("str type %T str=%q\n", str, str)	//输出: str type string str="true"	str = fmt.Sprintf("%t", b)	fmt.Printf("str type %T str=%q\n", str, str)	//输出: str type string str="h"	str = fmt.Sprintf("%c", myChar)	fmt.Printf("str type %T str=%q\n", str, str)	//第二种方式 strconv 函数	var num3 int = 99	var num4 float64 = 23.456	var b2 bool = true	//输出: str type string str="99"	str = strconv.FormatInt(int64(num3), 10)	fmt.Printf("str type %T str=%q\n", str, str)	// strconv.FormatFloat(num4, 'f', 10, 64)	// 说明: 'f' 格式 10:表示小数位保留10位 64 :表示这个小数是 float64	// 输出: str type string str="23.4560000000"	str = strconv.FormatFloat(num4, 'f', 10, 64)	fmt.Printf("str type %T str=%q\n", str, str)	//输出: str type string str="true"	str = strconv.FormatBool(b2)	fmt.Printf("str type %T str=%q\n", str, str)	//strconv 包中有一个函数 Itoa	//输出: str type string str="4567"	var num5 int64 = 4567	str = strconv.Itoa(int(num5))	fmt.Printf("str type %T str=%q\n", str, str)}

golang 中 string 转成基本数据类型

package mainimport (	"fmt"	"strconv")// golang 中 string 转成基本数据类型func main() {	// 输出: b type bool  b=true	var str string = "true"	var b bool	// b, _ = strconv.ParseBool(str)	// 说明	// 1. strconv.ParseBool(str) 函数会返回两个值 (value bool, err error)	// 2. 因为我只想获取到 value bool ,不想获取 err 所以我使用_忽略	b, _ = strconv.ParseBool(str)	//输出: b type bool  b=true	fmt.Printf("b type %T  b=%v\n", b, b)	// 输出: 	n1 type int64  n1=1234590	//			n2 type int n2=1234590	var str2 string = "1234590"	var n1 int64	var n2 int	n1, _ = strconv.ParseInt(str2, 10, 64)	n2 = int(n1)	//输出: n1 type int64  n1=1234590	fmt.Printf("n1 type %T  n1=%v\n", n1, n1)	//输出: n2 type int n2=1234590	fmt.Printf("n2 type %T n2=%v\n", n2, n2)	// 输出: f1 type float64 f1=123.456	var str3 string = "123.456"	var f1 float64	f1, _ = strconv.ParseFloat(str3, 64)	//输出: f1 type float64 f1=123.456	fmt.Printf("f1 type %T f1=%v\n", f1, f1)	// 输出: n3 type int64 n3=0	var str4 string = "hello"	var n3 int64 = 11	n3, _ = strconv.ParseInt(str4, 10, 64)	//输出: n3 type int64 n3=0	fmt.Printf("n3 type %T n3=%v\n", n3, n3)}

【2.2】运算符

golang 语言运算符注意点总结

++,-- 运算符

package mainimport (	"fmt"	_ "fmt")func main() {	//在golang中,++ 和 -- 只能独立使用.	var i int = 8	// var a int	// a = i++ //错误,i++只能独立使用	// a = i-- //错误, i--只能独立使用	// 编译出错	// if i++ > 0 {	// 	fmt.Println("ok")	// }	i++	// ++i // 错误,在golang没有 前++	fmt.Println("i=", i)	i--	// --i // 错误,在golang没有 前--	fmt.Println("i=", i)}

【2.3】典型流程控制示例

golang 语言 break 总结

package mainimport (	"fmt"	"math/rand"	"time")func main() {	//我们为了生成一个随机数,还需要个rand设置一个种子.	//time.Now().Unix() : 返回一个从1970:01:01 的0时0分0秒到现在的秒数	//rand.Seed(time.Now().Unix())	//如何随机的生成1-100整数	//n := rand.Intn(100) + 1 // [0 100)	//fmt.Println(n)	//随机生成1-100的一个数,直到生成了99这个数,看看你一共用了几次	//分析思路:	//编写一个无限循环的控制,然后不停的随机生成数,当生成了99时,就退出这个无限循环==》break	var count int = 0	for {		rand.Seed(time.Now().UnixNano())		n := rand.Intn(100) + 1		fmt.Println("n=", n)		count++		if n == 99 {			break //表示跳出for循环		}	}	fmt.Println("生成 99 一共使用了 ", count)	//这里演示一下指定标签的形式来使用 break	//break 语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块	//lable2:	for i := 0; i < 4; i++ {	lable1: // 设置一个标签		for j := 0; j < 10; j++ {			if j == 2 {				// break // break 默认会跳出最近的for循环				break lable1				// break lable2			}			//break : j=0,j=1; i=0,i=1,i=2,i=3;			//break lable1 : j=0,j=1; i=0,i=1,i=2,i=3;			//break lable2 : j=0,j=1; i 不会打印;			fmt.Println("j=", j)		}		fmt.Println("i=", i)	}}

golang 语言 continue 总结

package mainimport "fmt"func main() {	//continue案例	//这里演示一下指定标签的形式来使用lable2:	for i := 0; i < 4; i++ {		// lable1: // 设置一个标签		for j := 0; j < 10; j++ {			if j == 2 {				// continue				// continue lable1				continue lable2			}			// continue : i=0--3;j=0,1,3--9;			// continue lable1 : i=0--3;j=0,1,3--9;			// continue lable2 : j=0,1; i 不打印			fmt.Println("j=", j)		}		fmt.Println("i=", i)	}}

golang 语言 for 总结

package mainimport (	"fmt")func main() {	//for 循环的第一种写法	for i := 1; i <= 10; i++ {		fmt.Println("你好,尚硅谷", i)	}	//for 循环的第二种写法	j := 1        //循环变量初始化	for j <= 10 { //循环条件		fmt.Println("你好,尚硅谷~", j)		j++ //循环变量迭代	}	//for 循环的第三种写法, 这种写法通常会配合 break 使用	k := 1	for { // 这里也等价 for ; ; {		if k <= 10 {			fmt.Println("ok~~", k)		} else {			break //break就是跳出这个for循环		}		k++	}	//字符串遍历方式1-传统方式	var str string = "hello,world!北京"	for i := 0; i < len(str); i++ {		fmt.Printf("%c \n", str[i]) //使用到下标...	}	//字符串遍历方式1-传统方式	str2 := []rune(str) // 就是把 str 转成 []rune	for i := 0; i < len(str2); i++ {		fmt.Printf("%c \n", str2[i]) //使用到下标...	}	//字符串遍历方式2-for-range	str = "abc~ok上海"	for index, val := range str {		fmt.Printf("index=%d, val=%c \n", index, val)	}}

golang 语言 goto / return 总结

package mainimport (	"fmt")func main() {	var n int = 30	//演示goto的使用	fmt.Println("GOTO1")	if n > 20 {		goto label1	}	fmt.Println("GOTO2")	fmt.Println("GOTO3")	fmt.Println("GOTO4")label1:	fmt.Println("GOTO5")	fmt.Println("GOTO6")	fmt.Println("GOTO7")	//演示return的使用	fmt.Println("RETURN1")	if n > 20 {		return	}	fmt.Println("RETURN2")	fmt.Println("RETURN3")	fmt.Println("RETURN4")	fmt.Println("RETURN5")	fmt.Println("RETURN6")	fmt.Println("RETURN7")}

golang 语言 switch 总结

package mainimport (	"fmt")func main() {	//go 语言中 switch 匹配后不需要加 break 自动退出	var n1 int32 = 51	var n2 int32 = 20	switch n1 {	case n2, 10, 5: // case 后面可以有多个表达式		fmt.Println("ok1")	case 90:		fmt.Println("ok2~")	}	//switch 后也可以不带表达式,类似 if--else 分支来使用。【案例演示】	var age int = 10	switch {	case age == 10:		fmt.Println("age == 10")	case age == 20:		fmt.Println("age == 20")	default:		fmt.Println("没有匹配到")	}	//case 中也可以对 范围进行判断	var score int = 90	switch {	case score > 90:		fmt.Println("成绩优秀..")	case score >= 70 && score <= 90:		fmt.Println("成绩优良...")	case score >= 60 && score < 70:		fmt.Println("成绩及格...")	default:		fmt.Println("不及格")	}	//switch 后也可以直接声明/定义一个变量,分号结束,不推荐	switch grade := 90; { // 在golang中,可以这样写	case grade > 90:		fmt.Println("成绩优秀~..")	case grade >= 70 && grade <= 90:		fmt.Println("成绩优良~...")	case grade >= 60 && grade < 70:		fmt.Println("成绩及格~...")	default:		fmt.Println("不及格~")	}	//switch 的穿透 fallthrought	//在 case 语句块后添加 fallthrought 则会继续执行下一个 case	var num int = 10	switch num {	case 10:		fmt.Println("ok1")		fallthrough //默认只能穿透一层	case 20:		fmt.Println("ok2")		fallthrough	case 30:		fmt.Println("ok3")	default:		fmt.Println("没有匹配到..")	}}

golang 语言 while 总结

package mainimport "fmt"func main() {	//使用while方式输出10句 "hello,world"	//循环变量初始化	var i int = 1	for {		if i > 10 { //循环条件			break // 跳出for循环,结束for循环		}		fmt.Println("hello,world", i)		i++ //循环变量的迭代	}	fmt.Println("i=", i)	//使用的do...while实现完成输出10句”hello,ok“	var j int = 1	for {		fmt.Println("hello,ok", j)		j++ //循环变量的迭代		if j > 10 {			break //break 就是跳出for循环		}	}}

 

参考致谢

本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。

【1】尚硅谷_韩顺平_Go语言核心编程

【2】

【3】

 

转载地址:http://ismr.baihongyu.com/

你可能感兴趣的文章