Golang的结构,基本类型及语法

golang需要指定一个工作目录

▾ workspace
    ▾ src (用于存放go源码)
    ▾ pkg (放包)
    ▾ bin (编译出来的东西会放到这里)

go源码文件的第一行必须是

package name

当你import一个package的时候,他会解析出目录最后一个元素作为包名,以便在代码中使用。

Testing

go有一个轻量级的测试框架。go test 命令和testing 包

你只需要建立一个以_test.go结尾的文件,go test 会运行里面的所有TestXXX函数(这些函数是参数是 (t *testing.T)),如果函数调用了t.Errort.Fail,就认为测试失败。

我们给stringutil添加一个测试:

$GOPATH/src/github.com/moonsn/stringutil/reverse_test.go

package stringutil

import "testing"

func TestReverse(t *testing.T) {
    cases := []struct {
        in, want string
    }{
        {"Hello, world", "dlrow ,olleH"},
        {"Hello, 世界", "界世 ,olleH"}
        {"",""}
    }
    for _, c := range cases {
        got := Reverse(c.in)
        if got != c.want {
            t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
        }
    }
}

运行test

$ go test
ok      github.com/user/stringutil 0.165s

Remote Package

$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go example!

go get会自动fetch,build,insatll

func

package main

import "fmt"

func swap(x, y string) (string, string) {
    return y, x
}

func main() {
    a, b := swap("hello", "world")
    fmt.Println(a, b)
}
  • 函数参数类型在变量名之后,多个相同的连续类型可以只写最后一个。
  • 返回值类型写在参数列表之后。
  • 函数可以返回任意多个返回值。

var

package main

import "fmt"

var i, j int = 1, 2

func main() {
    var c, python, java = true, false, "no!"
    k := 3
    fmt.Println(i, j, c, python, java)
}
  • var 语句定义了一个变量的列表;跟函数的参数列表一样,类型在后面。
  • 就像在这个例子中看到的一样, var 语句可以定义在包或函数级别。
  • 变量定义可以包含初始值,每个变量对应一个。
  • 如果初始化是使用表达式,则可以省略类型;变量从初始值中获得类型。
  • 在函数中, := 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。
  • 函数外的每个语句都必须以关键字开始( var 、 func 、等等), := 结构不能使用在函数外。

基本类型

Go 的基本类型有Basic types

bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8 的别名

rune // int32 的别名
     // 代表一个Unicode码

float32 float64

complex64 complex128
package main

import (
    "fmt"
    "math/cmplx"
)

//可以像这样定义变量
var (
    ToBe   bool       = false
    MaxInt uint64     = 1<<64 - 1
    z      complex128 = cmplx.Sqrt(-5 + 12i)
)

func main() {
    const f = "%T(%v)\n" //T 类型 v变量
    fmt.Printf(f, ToBe, ToBe)
    fmt.Printf(f, MaxInt, MaxInt)
    fmt.Printf(f, z, z)
}

for

Go 只有一种循环结构—— for 循环。

基本的 for 循环除了没有了 ( ) 之外(甚至强制不能使用它们),看起来跟 C 或者 Java 中做的一样,而 { } 是必须的。

package main

import "fmt"

func main() {
    sum := 0
    for i := 0; i < 10; i++ {
        sum += i
    }
    fmt.Println(sum)
}

where ?

like this!!

package main

import "fmt"

func main() {
    sum := 1
    for sum < 1000 { //while(sum<1000)
        sum += sum
    }
    fmt.Println(sum)
}

那么全省略的话??

当然是无限循环了

package main

func main() {
    for {
    }
}

if

和for一样,省略了括号

package main

import (
    "fmt"
    "math"
)

func sqrt(x float64) string {
    if x < 0 {
        return sqrt(-x) + "i"
    }
    return fmt.Sprint(math.Sqrt(x))
}

func main() {
    fmt.Println(sqrt(2), sqrt(-4))
}

一样的地方还有:可以在条件前面定义一个局部变量

package main

import (
    "fmt"
    "math"
)

func pow(x, n, lim float64) float64 {
    if v := math.Pow(x, n); v < lim {
        return v
    }
    return v;
}

func main() {
    fmt.Println(
        pow(3, 2, 10),
        pow(3, 3, 20),
    )
}

defer

defer会延迟函数的执行,指导上层函数返回。(defer 的函数会执行并要入一个栈中)

package main

import "fmt"

func main() {
    fmt.Println("counting")

    for i := 0; i < 10; i++ {
        defer fmt.Println(i)
    }

    fmt.Println("done")
}

指针

var p *int;
i := 42
p = &i
fmt.Println(*p);//42

用法同c语言,但是没有指针运算。

结构体

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    p := &v
    p.X = 1e9
    fmt.Println(v)
}

数组

var arr [10]int