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.Error
或t.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