函数基础语法
函数关键字func ,主函数入口是main
函数参数格时区别于java之处有两点:1、变量声明在前,类型在后;2、同一类型不用多次知名类型,只需在类型前的变量声明时用逗号分隔
函数返回值区别于java之处,它可以返回多个值。java返回多个值往往需要采用数组,不同格式还需要使用map
函数返回值若是多个,主要有一个有返回名,则其他的都应该有返回名,否则报错;如果有多个返回值,必须加括号;如果只有一个返回值且有返回名,也必须加括号
变量基础语法
变量声明使用关键字var,在函数内部也可以不使用var,直接通过 := 替代var定义。
但是在函数外部的所有语句必须要使用关键字开始,这就意味在函数外部不能使用 := 声明变量
Go 的基本类型有
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 的别名
rune // int32 的别名
// 代表一个Unicode码
float32 float64
complex64 complex128
常量
常量定义格式
const identifier [type] = value
常量定义可以省略类型说明符
常量使用关键字const,常量不能使用 :=
常量的数据类型值可以是bool,数字型,字符串
数字型的常量是没有大小和符号的,可以使用任意精度
iota只能在常量表达式中使用,可用于枚举,在每遇到一个新的const时,iota变为了,若在同一个结构体,他会像其它语言的枚举一样
实例代码:
const (
x = iota
_
y
z = "zz"
k
p = iota
r = true
s
t = iota
)
fmt.Println(x,y,z,k,p,r,s, t)
输出结果
自定义类型与别名
type MyInt1 int //自定义类型 MyInt1是一个全新的类型
type MyInt2 = int // MyInt2是int的别名 本质上是同一种类型
流程控制
- for
for相对于Java,区别仅在于for后面的部分不需要小括号
go语言只有for循环,用for代替java的while
- if
if后面的表达式也不需要小括号
if语句的表达式之前,可以有一个简单的语句,例如变量初始化
- defer 延迟函数 Java没有
指针
和C语言用法一致,但是go语言的指针没有指针运算
闭包
闭包是返回的函数与返回函数中关联的外部变量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2nEArcZA-1580530644853)(en-resource://database/699:1)]
输出结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HJCKp2zm-1580530644854)(en-resource://database/701:1)]
结构体
“type 结构体名称 struct {}” 结构体中变量,用结构体变量加点访问
结构体比较
结构体只能比较是否相等,不能比较大小
相同类型的结构体才能比较,结构体是否相同,不但与属性类型有关,还与属性的顺序有关
如果所有结构体成员都可以比较,则根据属性顺序逐个比较,如果每一项都相等,那么这两个结构体相等
可比较的类型包括bool、数值型、字符、指针、数组等
map、切片、函数是不能比较的
数组
"var 数组名称 [数组大小]数组元素类型
数组是值类型,切片是引用类型
数组初始化
func main {
// 方式1
var a [2] string
a[0] = "hhe"
a[1] = "cd"
// 方式2
arr := []int{1,2,3,4}
fmt.Println(arr[:2])
}
go数组与Java另一个不同之处,go可以使用类似python的slice切片方式访问数组
range
range 可以搭配for循环使用,遍历数组或者map
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
// i 是对应的索引 v对应的时所在索引的值
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
切片
切片格式
var identifier []type
切片初始化格式var slice1 []type = arr1[start:end]
切片是一个长度可变的数组
一个数组的切片和这个数组的其他切片是共享存储的
切片是引用,不需要额外的内存,比数组更有效率
字符串
字符串是一种值类型,且值不可变。可以理解是一个定长的字节数组
字符串创建后,不能修改
与C不同的是,它不是通过特殊字符‘\0’限定,而是通过长度限定
字符串的内容可以通过索引来访问,类似数组索引的形式
map
go语言中,map的创建必须采用make函数,不像java采用new。如果不用make,也可以在声明同时,用构造的形式
如果只声明map类型,直接使用map会报错
map中的key是无序的
map 切片
方法和接口
Go没有类,但是可以在结构体上定义方法。方法的接收者出现在func和方法名之间
// 结构体
type Vert struct {
x int
y int
z int
}
// 在结构体上定义方法
func (p *Vert) distance() float64 {
return math.Sqrt(float64(p.x*p.x + p.y*p.y + p.z*p.z))
}
func main() {
vert : = Vert{1,2,3}
vert.distance()
}
接口
接口是一组方法定义的集合
与java不同的是实现接口没有显示的关键字implement。而是通过隐式的方式
定义接口方式: type 接口名 interface { 方法名 }
// 声明接口
type SalaryCalculator interface {
CalculateSalary() int
}
type Permanent struct {
empId int
basicpay int
pf int
}
type Contract struct {
empId int
basicpay int
}
// 隐式实现接口
func (p Permanent) CalculateSalary() int{
return p.basicpay + p.pf
}
func (c Contract) CalculateSalary() int {
return c.basicpay
}
// 使用接口
func totalExppense(s []SalaryCalculator) int {
expense := 0
for _,v := range s {
expense += v.CalculateSalary()
}
return expense
}
类型断言
类型断言用于提取接口的底层值
如i.(T)
接口i的具体类型是T
func assert(i interface{}) {
s := i.(int)
fmt.Println(s)
}
func assert1(i interface{}) {
i,v := i.(int)
fmt.Println(i,v)
}
func main() {
var s interface{} = 56
assert(s)
var s1 interface{} = "hello"
assert1(s1)
}
类型选择
语法: switch i.(type) i是inerface{}类型
func findType(i interface{}) {
// 类型选择
switch i.(type) {
case string:
fmt.Println("string")
case int:
fmt.Println("int")
case float64:
fmt.Println("flaot")
default:
fmt.Println("default")
}
}