golang语言特性
-
垃圾回收
- 内存自动回收,再也不需要开发人员管理内存
- 开发人员专注业务实现,降低了心智负担
- 只需要new分配内存,不需要释放
-
天然并发
- 从语言层面支持并发,无需第三方库
- goroute,轻量级线程,创建成千上万个goroute成为可能
- 基于CSP(Communicating Sequential Process)模型实现
-
channel
- 管道,类似unix/linux中的pipe
- 多个goroute之间通过channel进行通信
- 支持任何类型
func main() {
pipe := make(chan int,3)
pipe <- 1
pipe <- 2
}
- 多返回值
func calc(a int, b int)(int,int) {
sum := a + b
avg := (a+b)/2
return sum, avg
}
- 试试Hello world
package main
import(
“fmt”
)
func main() {
fmt.Println(“hello world”)
}
- 自带包管理
- 和python一样,把相同功能的代码放到一个目录,称之为包
- 包可以被其它包引用
- main包是用来生成可执行文件,每个程序只有一个main包
- 包的主要用途是提高代码的可复用性
基本数据类型和操作符
golang保留关键字
- break
- default
- func
- interface
- select
- case
- defer
- go
- map
- struct
- chan
- else
- goto
- package
- switch
- const
- fallthough
- if
- range
- type
- continue
- for
- import
- return
- var
go程序的基本结构
package main
import(
“fmt”
)
func main() {
fmt.Println(“hello world”)
}
1 任何一个代码文件隶属于一个包
2 import 关键字,引入其它包:
import(“fmt”)
import(“os”)也可写成:
import(
“fmt”
“os”
)
3 golang可执行程序,package main,并且有且只有一个main入口
4 包中函数的调用:
- 同一个包中函数,直接调用
- 不同包中函数,通过包名+点+
函数名进行调用
5 包访问控制规则:
- 大写意味着这个函数/变量是可导出的
- 小写意味着这个函数/变量是私有的, 包外部不能访问
6 包的别名
package main
import(
a "add"
)
func main () {
fmt.Println(“result:”, a.Name)
fmt.Println(“result:”, a.age)
}
7 init函数
每个源文件都可以包含一个init函数,这个init函数自动被go运行框架调用
package main
import(
_ “add”
)
// 不用的变量或包,应该用_接收
func init () {
fmt.Println(“initialized”)
}
函数声明和注释
函数声明: func 函数名字 (参数列表) (返回值列表){}
func add{
}
func add(a int, b int) int{
}
func add(a int, b int) (int, int){
}
注释:
两种注释,单行注释: // 和多行注释 /* */
常量
- 常量使用const 修饰,代表永远是只读的,不能修改。
- const 只能修饰boolean,number(int相关类型、浮点类型、complex)和string
- 语法:
const identifier [type] = value
,其中type可以省略
const b string = “hello world”
const b = “hello world”
const Pi = 3.1414926
const a = 9/3
const c = getValue() // Error
常量比较优雅的写法
const (
a = 0
b = 1
c = 2
)
// 更加专业的写法
const (
a = iota
b //1
c //2
)
变量的声明
语法:var identifier type
var a int
var b string
var c bool
var d int = 8
var e string = "hello world"
// 也可以这样写
var (
a int //默认为0
b string //默认为””
c bool //默认为false
d int = 8
e string = “hello world”
)
// 还可以省略类型
var (
a int //默认为0
b string //默认为””
c bool //默认为false
d = 8
e = “hello world”
)
练习:写一个程序获取当前运行的操作系统名称和PATH环境环境变量的值,并打印在终端
package main
import (
"os"
"fmt"
)
func main() {
var goos string = os.Getenv("OS")
fmt.Printf("The operating system is: %s\n", goos)
path := os.Getenv("PATH")
fmt.Printf("Path is %s\n", path)
}
值类型和引用类型
- 值类型:变量直接存储值,内存通常在栈中分配,如:
var i = 5
- 引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配,通过GC回收。
基本数据类型int、float、bool、string以及数组和struct;
指针、slice、map、chan等都是引用类型
变量的作用域
在函数内部声明的变量叫做局部变量,生命周期仅限于函数内部;
在函数外部声明的变量叫做全局变量,生命周期作用于整个包,如果是大写的,则作用于整个程序。
小练习: 请指出下面程序的输出是什么?
package main
import "fmt"
var a string
func main() {
a = "G"
fmt.Println(a)
f1()
}
func f1() {
a := "0"
fmt.Println(a)
f2()
}
func f2() {
fmt.Println(a)
}
// G 0 G
数据类型和操作符
逻辑操作符: == 、!=、<、<=、>和 >=
数学操作符:+、-、*、/等等
字符类型:var a byte
字符串类型: var str string
字符串表示两种方式:
- 双引号 “”
- 反引号 ``
package main
import "fmt"
func main() {
var str = "hello world\n\n"
var str2 = `hello \n \n \n
this is a test string
This is a test string too·`
fmt.Println("str=", str)
fmt.Println("str2=", str2)
}