基础语法
//程序所属包(必须在程序第一行)
package main
//导入依赖包
import "fmt"
//常量定义
const NAME string = "go"
//全局变量的声明与赋值
var a string = "go"
//一般类型声明
type go int
//结构的声明
type Learn struct {
}
//接口声明
type Ilearn interface {
}
//函数定义
func learnGo() {
fmt.Print("learnGo")
}
//main()函数
func main() {
fmt.Print("Hello world!")
}
Package包的用法
- package是最基本的分发单位和工程管理中依赖关系的体现;
- 每个GO语言源代码文件开头都拥有一个package声明,表示源码文件所属代码包;
- 要生成GO语言可执行程序,必须要有main的package包,且必须在该包下有main()函数;
- 同一路径下只能存在一个package,一个package可以拆成多个源文件组成;
import概念及原理
概念
- import语句可以导入源代码文件所依赖的package包;
- 不得导入源代码文件中没有用到的package,否则GO语言编译会报编译错误;
- import语法格式主要有两种形式:
//第一种
import "package1"
import "package2"
//第二种【推荐】
import(
"package1"
"package2"
)
原理
- 如果一个main导入其他包,包将被顺序导入;
- 如果导入的包中依赖其他包(包A),会首先导入包A,然后初始化A包中常量和变量,最后如果A包中有int,会自动执行init();
- 所有包导入完成后才对main中变量和常量进行初始化,然后执行main中的init函数(如果存在),最后执行main函数;
- 如果一个包被导入多次则该包只会被导入一次;
别名,".","_"的使用
import "fmt"
import alias "fmt"
- 点(.)操作的含义是:点(.)标识的包导入后,调用该包中函数时可以省略前缀包名【不建议使用点(.),容易造成函数冲突】;
import . "fmt"
- 下划线( _ )操作的含义是:导入该包,但不导入整个包,而是执行该包中的init的函数,因此无法通过包名来调用包中的其他函数。使用下划线( _ )操作往往是为了注册包里的引擎,让外部可以方便的使用;
import _ "fmt"
数据类型
数值类型
字符串类型
布尔型
派生类型
- 指针类型(Pointer)
- 数组类型
- 结构化类型(struct)
- Channel类型 (chan)
- 函数类型 (func)
- 切片类型 (slice)
- 接口类型 (interface)
- Map类型 (map)
类型零值和类型别名
- 类型零值不是空置,而是某个变量被声明后的默认值,一般情况下,值类型的默认值为0,布尔型默认值为false,字符串类型默认值为空字符串;
var i int32
var j float32
var b bool
var d complex64
//注意:别名类型不能进行运算(相同的别名类型可以
)
type go int32
func main()
{
var i go
}
类型所占存储大小
变量
单个变量声明和赋值
var a int
- 赋值格式:<变量名称> = <值,表达式,函数等>
a = 1
- 声明和赋值同时进行:var <变量名称> [变量类型] = <值,表达式,函数等>
var a int = 1
var(
i int
j float32
name string
c int = 1989
)
var a,b,c int = 1,2,3
var a,b,c = 1,1.2,4
a,b: = 1,2 //简写方式,只能用在函数体内
- 全局变量的声明必须使用var关键字,局部变量则可以省略;
- 特殊变量下划线 "_"【可以理解成把这个值丢进垃圾桶,程序运行时不在需要这个值】;
var a,_,c = 11,21.2,4
输出 11,4
变量类型转化
- Go 中不存在隐式转换,类型转换必须是显示的;
- 类型转换只能发生在两种兼容类型之间(int和bool是无法转化的);
- 类型转换格式:<变量名称> [:] = <目标类型> (<需要转换的变量>)【冒号可有可无】
var a int = 3
c := float32(a)
输出:3
var b float32 = 3.01
c := int32(b)
输出:3
转换会有精度的损失
变量可见性规则
- 大写字母开头的变量是可导出的,也就是其他包可以读取,是公用变量;
- 小写字母开头的就是不可导出的,是私有变量
var a = "go"
var Learn = "go"
常量
常量定义形式和类型范围
- 常量定义形式可分为显式和隐式
1.显式:const identifier [type] = value
2.隐式:const identifier = value
(通常叫无类型常量)
const learn string = 'go'
const name = '007'
const(
learn string = 'go'
name = '007'
)
const learn,name string = 'go','007'
const a,b = 1,'go'
- 常量可以使用内置表达式定义,例如:len(),unsafe.Sizeof()等;
const a,b = 1,'go'
const alen = len(a)
- 常量范围目前支持布尔型、数字型(整数型、浮点型和复数)和字符串型;
特殊常量iota的使用
const a = iota
const b = iota
输出 0 0
- const中每新增一行常量声明将使iota计数一次;
const(
b = iota
c = iota
)
输出 0 1
- iota常见使用法:
1.跳值使用法
2.插队使用法
3.表达式隐式使用法
4.单行使用法
//跳值【使用下划线】
const(
a = iota
b = iota
_
c = iota
)
输出 0 1 3
//插队
const(
a = iota
b = 5.21
c = iota
)
输出 0 5.21 2
//表达式隐式
const(
a = iota * 2
b = iota
c = iota
)
输出 0 1 2
const(
a = iota * 2
b
c
)
输出 0 2 4
const(
a = iota * 2
b = iota * 3
c
d
)
输出 0 3 6 9
//单行使用法
const (
a,b = iota,iota+3
c,d
f = iota
输出 a = 0 b =3 c = 1 d=4 f=2
)
控制语句
- 条件语句if,if...else,嵌套if,else if;
func main() {
a := 1
if a > 0 {
}
}
func main() {
/* 定义局部变量 */
var grade string = "B"
var marks int = 90
switch marks {
case 90: grade = "A"
case 80: grade = "B"
case 50,60,70 : grade = "C"
default: grade = "D"
}
fmt.Printf("你的等级是 %s\n", grade );
}
func main() {
//无限循环 true可以去掉
for true {
fmt.Printf("这是无限循环。\n");
}
//普通循环
sum := 0
for i := 0; i <= 10; i++ {
sum += i
}
//类似while
for sum <= 10{
sum += sum
}
fmt.Println(sum)
//foreach range循环
strings := []string{"google", "runoob"}
for i, s := range strings {
fmt.Println(i, s)
}
numbers := [6]int{1, 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
}
func main(){
goto One
fmt.Print("中间代码")
One:
fmt.Print("代码一")
}