5.1 IF ELSE
If else 的例子如下,需要注意的是花括号和条件表达式位于同一行。
package main import ( "fmt" ) func increment(i *int) { *i++ } func main() { if num := 9; num < 0 { fmt.Println(num, "is negative") } else if num < 10 { fmt.Println(num, "has 1 digit") } else { fmt.Println(num, "has multiple digits") } }
5.2 SWITCH CASE
Switch case 能组织多条件表达式,例子如下:
package main import ( "fmt" ) func increment(i *int) { *i++ } func main() { i := 2 switch i { case 1: fmt.Println("one") case 2: fmt.Println("two") default: fmt.Println("none") } } ------------------ > Output: command-line-arguments two > Elapsed: 0.834s > Result: Success
Golang 中只有一个循环表达的关键字,不同形式的循环表达式如下:
package main import ( "fmt" ) func increment(i *int) { *i++ } func main() { i := 0 sum := 0 for i < 10 { sum += 1 i++ } fmt.Println(sum) } -------------------- > Output: command-line-arguments 10 > Elapsed: 0.828s > Result: Success
上面的例子和 C 语言中的 while
循环类似,更为正式的循环表达形式如下:
package main import ( "fmt" ) func main() { sum := 0 for i := 0; i < 10; i++ { sum += i } fmt.Println(sum) } ----------------- > Output: command-line-arguments 45 > Elapsed: 0.832s > Result: Success
Go 语言中的死循环定义如下:
for { }
Go 语言可以使用指针,指针存储变量的地址,指针用*来定义。指针的定义和所指数据的类型相关:
var ap *int
这里的 ap 是指向整型数据的指针,&
用于获取所变量的地址。
a :=12 ap = &a
*
用于获取指针所指的地址的值。
fmt.Println(ap) // => 0xc000016088 fmt.Println(*ap) // => 12
指针通常用于将结构体做为参数传递。
package main import ( "fmt" ) func increment(i *int) { *i++ } func main() { i := 10 increment(&i) fmt.Println(i) } //=> 11
main 包中 main 函数是 golang 程序的入口。我们可以定义多个函数并调用。例如:
package main import ( "fmt" ) func add(a int, b int) int { c := a + b return c } func main() { fmt.Println(add(2, 1)) } --------------- > Output: command-line-arguments 3 > Elapsed: 0.788s > Result: Success
从上面的例子中我们可以看出,Golang 中的函数用 func
关键字加上函数名, 后面是附带数据类型的参数,最后是函数的返回类型。
函数的返回值可以被预先定义,例子如下:
package main import ( "fmt" ) func add(a int, b int) (c int) { c = a + b //注意这里没有冒号,并且 return 直接返回,不需要加变量名 return } func main() { fmt.Println(add(2, 1)) } //=> 3
这里 c
定义为返回值,因此变量 c 将会被自动返回,无需在函数最后的 return 中声明。你也可以定义一个多个返回值的函数,使用 , 进行分割。
package main import ( "fmt" ) func add(a int, b int) (int, string) { c := a + b return c, "successfully added" } func main() { sum, message := add(2, 1) fmt.Println(message) fmt.Println(sum) } //=> successfully added //=> 3
Golang 不是完全的面向对象语言,但是支持很多面向对象的特性,例如:结构体,接口,方法等。
9.1 结构体
结构体是有类型,不同变量的集合。例如我们想定义 Person 类型,其中包括:姓名,年龄,性别。例如:
type person struct { name string age int gender string }
定义好了person结构体后,我们现在来使用它:
//方式 1: 指定属性和值 p = person{name: "Bob", age: 42, gender: "Male"} //方式 2: 只指定值 person{"Bob", 42, "Male"}
我们可以使用.符号访问这些属性:
p.name //=> Bob p.age //=> 42 p.gender //=> Male
你也可是使用指针访问结构体的属性:
pp = &person{name: "Bob", age: 42, gender: "Male"} pp.name //=> Bob
9.2 方法
方法是一种带有接受器的特殊函数。接收器可以是值或者指针。例子如下:
package main import "fmt" // 定义结构体 type person struct { name string age int gender string } // 定义方法 func (p *person) describe() { fmt.Printf("%v is %v years old.", p.name, p.age) } func (p *person) setAge(age int) { p.age = age } func (p person) setName(name string) { p.name = name } func main() { pp := &person{name: "Bob", age: 42, gender: "Male"} pp.describe() // => Bob is 42 years old pp.setAge(45) fmt.Println(pp.age) //=> 45 pp.setName("Hari") fmt.Println(pp.name) //=> Bob 注意这里和上面的区别 }
从上面的例子我们可以看出,使用 . 操作符调用方法,例如 pp.describe
。需要注意的是,接收器是指针的话,我们传递的是值的引用,这意味着我们在方法做修改将会反映到变量 pp 上。不会创建对象的拷贝,将会节省内存。
从上面的例子我们可以看出,age 的值被改变了,而 name 的值并没有改变。这是因为方法 setName 的接受器不是指针。
9.3 接口
Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。Golang 中的接口是方法的集合,接口有助于将同类型的属性组合起来,让我们一起来看一个 anminal
的接口。
type animal interface { description() string }
这里的 animal
是接口类型,我们来创建两种类型的 animal
并实现接口。
package main import ( "fmt" ) type animal interface { description() string } type cat struct { Type string Sound string } type snake struct { Type string Poisonous bool } func (s snake) description() string { return fmt.Sprintf("Poisonous: %v", s.Poisonous) } func (c cat) description() string { return fmt.Sprintf("Sound: %v", c.Sound) } func main() { var a animal a = snake{Poisonous: true} fmt.Println(a.description()) a = cat{Sound: "Meow!!!"} fmt.Println(a.description()) } -------------------------- > Output: command-line-arguments Poisonous: true Sound: Meow!!! > Elapsed: 0.881s > Result: Success
在 main
函数中,我们创建可一个 animal
类型的变量 a
。我们把 snake
和 cat
类型赋值给 animal
,使用 Println
输出 a.description
。
我们在 cat 和 snake 中使用不同的方式实现了 describe
方法,我们得到了不同类型的输出。