Go语言初识

文章目录

为了CloudFoundry项目需要,学习了一下Go语言,下面是个人学习Go语言的总结。

软件工程的思想指导了go语言的设计
清晰简洁的依赖性管理
清晰的语法
清晰的语义
– 无指针运算
– 没有隐式的数字类型转换
– 数组边界检查
– 没有类型别名
重组合轻继承
更加简单的编程模式(垃圾回收,并发)
简单易用的编程辅助工具(go, gofmt, godoc, gofix)

程序基本结构

变量的声明

1
2
3
var str string
var arr [4]string
arr arr = [4]string{"joshua", "zhang", "hello", "world"}

数组的赋值需要注意:

每个赋值的元素都需要相应的整数索引 
常量表达式可以用作索引 
没有索引的元素使用前置元素的索引值加一最为当前元素的索引值 
数组中未赋值的元素,设为零值 
如果用于赋值的元素数量超过数组的最大长度,将产生错误,代码样例如下:
1
2
3
buffer :=[10]string{}    
intSet :=[6]int{1,2,3,4,5} //len(intSet) == 6
days :=[...]string{"Sat","Sun"} //len(days) == 2

map类型

由(键:元素值)对构成的无序组对,作为索引值的键必须唯一。键和元素值的类型可以不同 
未初始化的映射值为nil 
键的类型不能是函数,映射,切片,如果键的类型是接口,比较操作符必须针对动态键值实现相应的比较方法 

声明:

映射=map[键类型]元素类型 
(map)获取长度;索引获取元素 
通过赋值添加元素;delete()删除元素 
用make()获取新的空映射 
映射的初始容量设定不会限制它的长度 
映射会根据存储元素的数量自动调整,nil映射除外 

列举几种定义方式

1
2
3
4
filter := [10]float32{-1, 4:-0.1, -0.1, 9:-1}
note := map[string]float32{
"GO": 16.35, "DO" :18.35,
}

使用案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

func main {
var coutryCapitalMap map[string]string
/* create a map*/
coutryCapitalMap = make(map[string]string)

/* insert key-value pairs in the map*/
countryCapitalMap["France"] = "Paris"
countryCapitalMap["Italy"] = "Rome"
countryCapitalMap["Japan"] = "Tokyo"
countryCapitalMap["India"] = "New Delhi"

/* print map using keys*/
for country := range countryCapitalMap {
fmt.Println("Capital of",country,"is",countryCapitalMap[country])
}

/* test if entry is present in the map or not*/
captial, ok := countryCapitalMap["United States"]
/* if ok is true, entry is present otherwise entry is absent*/
if(ok){
fmt.Println("Capital of United States is", capital)
}else {
fmt.Println("Capital of United States is not present")
}
}

函数声明

绑定标识符、函数名 
声明了结果参数的函数,函数体语句一定要返回结果 
一个函数声明可以没有函数体。函数体的实现可以在Go语言之外 
每Go程序具有至少一个函数,它一般是main(),以及所有的最琐碎程序可以定义附加函数

定义函数

1
2
3
4
5
6
7
8
9
10
11
func max(num1, num2 int) int
{

result int

if (num1 > num2) {

result = num1
} else {
result = num2
}
return result
}

接口声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 声明一个接口 */
type Shape interface {
area() float64
}

/* 声明一个结构体circle */
type Circle struct {
x,y,radius float64
}

/* 定义一个方法 (implementation of Shape.area())*/
func(circle Circle) area() float64 {
return math.Pi * circle.radius * circle.radius
}
/* define a method for shape */
func getArea(shape Shape) float64 {
return shape.area()
}
/* 主函数调用*/
func main() {
circle := Circle{x:0,y:0,radius:5}
fmt.Printf("Circle area: %fn",getArea(circle))
}

常量声明

1
2
3
4
5
6
7
8
const Pi float64 = 301418926 
const zero = 0.0
const(
size int64 = 1024
eof = -1
)
const a, b, c = 3, 4, "ff" // a = 3, b = 4, c = ff,
const u, v float32 = 0,3 //u=0.0 v=3.0

声明变量

如果指定类型,每个变量都是指定类型    
如果没有指定类型,变量类型通过表达式赋值推断 
函数体内不能声明从未使用的变量 
1
2
3
4
5
6
const(
i int
u, v, s = 2.1 ,3.0, "bar"
)
const a, b, c = 3, 4, "ff" // a = 3, b = 4, c = ff,
const u, v float32 = 0,3 //u=0.0 v=3.0

指针

声明指针

1
2
var ip *int        /* pointer to an integer */
var fp *float32 /* pointer to a float */

举例

1
2
3
4
5
6
7
8
9
10
package main
import "fmt"
func main() {
var a int= 20
var ip *int /* 声明一个指针 */
ip = &a /* 给指针赋值 */
fmt.Printf("Address of a variable: %xn", &a ) /* 输出为:10328000 */
fmt.Printf("Address stored in ip variable: %xn", ip ) /* 输出为:10328000 */
fmt.Printf("Value of *ip variable: %dn", *ip ) /* 输出为:20 */
}

结构体

1
2
3
4
5
6
type Books struct {
title string
author string
subject string
book_id int
}

赋值语句(Assignments)

左侧操作数必须是可寻址的,或是空操作符
X op y  <=>  x= x op y  

多元赋值 (一次向左侧赋多个值)
空标识符的赋值,忽略右侧的具体值

赋值执行的两个阶段:
左侧由索引表达式和指针转向产生操作数,和右侧 的表达式以通常的顺序执行
赋值以从左到右的顺序执行

循环语句

for循环

1
2
3
For x <100{ } 
For int i:=0;i<20;i++{}
For I,v :=range arr {}

continue

goto

1
2
3
4
5
6
7
8
9
LOOP: for a < 20 {
if a == 15 {
/* skip the iteration */
a = a + 1
goto LOOP
}
fmt.Printf("value of a: %dn", a)
a++
}