也许是最简洁版本,一篇文章上手Go语言(中)

| 选择喜欢的代码风格  

5. 条件表达式


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

6. 循环


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 {
}

7. 指针


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

8. 函数


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

9. 方法,结构体,接口


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。我们把 snakecat 类型赋值给 animal,使用 Println 输出 a.description

我们在 catsnake 中使用不同的方式实现了 describe 方法,我们得到了不同类型的输出。

Golang 扩展阅读:




发表评论