Golang|01 基础语法
1. 变量和常量
golang中变量的定义结构是:var 变量名 类型
。golang中内建变量类型有:
- bool, string
- (u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr(指针)未指定长度时根据操作系统是多少位来决定
- byte, rune(长度32位,相当于 char,解决多国语言问题)
- float32, float64, complex64, complex128 可以看到golang中没有char, 只有rune
1.1 变量
- 变量都有默认值
func variableZeroValue() {
//golang 给定义的变量都会给定默认值,数值型默认是0, string默认值是“”空字符串(不是nil)
var a int
var s string
fmt.Printf("%d %q\n", a, s) //输出:0 "", %q打印string时会打印出“”, 表示引用
}
- 变量定义时赋初值,可以连续为多个变量赋值
func variableInitialValue() {
var a, b int = 3, 4
var s string = "abc"
fmt.Println(a, b, s) //输出:3 4 abc
}
- 变量定义时赋初值支持类型推导
func variableTypeDeduction() {
//定义并赋值,可以不显式的指定类型
var a, b, c, s = 3, 4, true, "def"
fmt.Println(a, b, c, s) //输出:3 4 true def
}
- 使用
:=
可以省略var
,简短变量声明赋值,但是这个方式不能在func
外使用
func variableShorter() {
a, b, c, s := 3, 4, true, "def"
b = 5
fmt.Println(a, b, c, s) //输出:3 4 true def
}
- 可以使用
var ()
一次定义多个变量,可以在func
外使用,也可以在func
内使用
var (
aa = 3
ss = "kkk"
)
func variablePrint() {
fmt.Println(aa, ss) ///输出:3 true kkk
}
- 类型转换都是强制的,没有默认的类型转换
func calcTriangle(a, b int) int {
var c int
// math.Sqrt(a*a + b*b) // 错误, a*a + b*b是int类型,Sqrt函数传入参数是float64, 需要强制转换
// c = math.Sqrt(float64(a*a + b*b)) //错误, c是int类型,Sqrt函数返回float64, 需要强制转换
c = int(math.Sqrt(float64(a*a + b*b))) //正确
return c
}
1.2 常量和枚举
- const数值可以作为各种类型使用
func consts() {
const (
filename = "abc.txt"
a, b = 3, 4
)
var c int
c = int(math.Sqrt(a*a + b*b)) // 正确,const数值可以作为各种类型使用
fmt.Println(filename, c) //输出:abc.txt 5
}
枚举是一类特殊的常量,golang中没有枚举的关键字,所以一般都是使用const表示
- iota表示一组自增值, 可以参与运算
func enums() {
const (
cpp = iota // 0
_ // 忽略掉1
python // 2
golang // 3
javascript // 4
)
const (
b = 1 << (10 * iota)
kb //相当于 1 << (10 * 1)
mb //相当于 1 << (10 * 2)
gb
tb
pb
)
fmt.Println(cpp, javascript, python, golang) //输出: 0 4 2 3
fmt.Println(b, kb, mb, gb, tb, pb) //输出: 1 1024 1048576 1073741824 1099511627776 1125899906842624
}
2. 条件语句
2.1 if
语句
- if的条件里不需要括号
- if的条件里可以赋值
- if的条件里赋值的变量作用域就在这个if语句里面
func printFile(filename string){
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
}
2.2 switch
语句
- 和
if
一样,switch
的判断条件里也是不需要括号的 switch
会自动break
,除非使用fallthrough
switch
后可以没有表达式
func eval(a, b int, op string) int {
var result int
switch op {
case "+":
result = a + b
case "-":
result = a - b
case "*":
result = a * b
case "/":
result = a / b
default:
panic("unsupported operator:" + op)
}
return result
}
3. 循环
golang
中没有while
, 因为while
的语义其实很容易用for
替换- for 的条件里不需要括号
- for 的条件里可以省略初始条件,结束条件,递增表达式
// 整数转二进制
func convertToBin(n int) string {
result := ""
for ; n > 0; n /= 2 {
lsb := n % 2
result = strconv.Itoa(lsb) + result
}
return result
}
- 省略初始条件,相当于 while
for scanner.Scan(){
fmt.Println(scanner.Text())
}
- 省略所有条件,无限循环/死循环, 因为go是支持并发的,所以这种写法在go中很常见
for {
fmt.Println("abc")
}
4. 函数
- 函数的定义形式:
func 函数名(传入参数) [返回值]{
}
- 可以返回多个返回值
func div(a, b int) (int, int) {
return a / b, a % b
}
- 函数返回多个值时可以起名字,但仅用于非常简单的函数,对于调用者而言没有区别
func div(a, b int) (q, r int) {
q = a / b
r = a % b
return
}
- 函数可以作为参数,函数式编程
func apply(op func(int, int) int, a, b int) int{
fmt.Printf("Calling %s with %d, %d\n",
runtime.FuncForPC(reflect.ValueOf(op).Pointer()).Name(),
a, b)
return op(a, b)
}
- go中只有可变参数列表,没有默认参数,函数重载
func sumArgs(values ...int) int {
sum := 0
for i := range values{
sum += values[i]
}
return sum
}
5. 指针
- golang中的指针是不能运算的,即不能像C/C++中那样将指针进行
p++, p--, p = p+10
这类的操作。正是因为指针可以运算导致C/C++的指针特别灵活
// 通过指针来交换值
func swap(a, b *int){
*b, *a = *a, *b
}
- Go语言的参数传递只有值传递一种方式, C/C++中有值传递和引用传递,Python/Java除了简单的自建类型基本都是引用传递。
- 原文作者:Binean
- 原文链接:https://bzhou830.github.io/post/20180502Go%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。