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 方法,我们得到了不同类型的输出。