概述
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。
Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。
Go 语言特色
- 简洁、快速、安全
- 并行、有趣、开源
- 内存管理、数组安全、编译迅速
Go 语言用途
Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。
对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。
第一个 Go 程序
接下来我们来编写第一个 Go 程序 hello.go(Go 语言源文件的扩展是 .go),go 不需要像java一样必须创建一个class,代码如下:
hello.go 文件
1 2 3 4 5 6 7
| package main
import "fmt"
func main() { fmt.Println("Hello, World!") }
|
运行实例 »
Go 语言结构
第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
下一行 import “fmt” 告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。
下一行 func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。
下一行 fmt.Println(…) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
注意:需要注意的是 {
不能单独放在一行,所以以下代码在运行时会产生错误:
1 2 3 4 5 6 7 8
| package main
import "fmt"
func main() { fmt.Println("Hello, World!") }
|
要执行 Go 语言代码可以使用 go run 命令。
执行以上代码输出:
1 2
| $ go run hello.go Hello,World!
|
此外我们还可以使用 go build 命令来生成二进制文件:
1 2 3 4 5
| $ go build hello.go $ ls hello hello.go $ ./hello Hello,World!
|
GO 基础语法
Go 程序中一行代表一个语句,不需要像 C 和 Java 中一样加 ;
结尾。如果想在一行内写多个语句必须要加 ;
单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。
变量
Go 变量是类型敏感的,但是和后来的 Java 一样是支持类型推断的,我们可以这样声明或赋值变量。
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
| package main
import "fmt"
var ( m = 1 n = 2 )
func main() { var a string a = "a" fmt.Println(a)
var b = "b" c := "c" fmt.Println(b, c)
var d, e, f string d, e, f = "d", "e", "f" g, h := "g", "h" fmt.Println(d, e, f, g, h, m, n) }
|
常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package main
import "fmt"
func main() { const LENGTH int = 10 const WIDTH int = 5 area := LENGTH * WIDTH fmt.Printf("面积为 : %d", area) const a, b, c = 1, false, "str" const ( d = 'd' e = 'e' ) }
|
iota
常量计数器,const 中每增加一个常量便会加一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package main
import "fmt"
func main() { const ( a = iota b = iota c ) fmt.Println(a, b, c) const ( d = 5 * iota e f = "f" g = iota ) fmt.Println(d, e, f, g) }
|
运算符
Go 语言运算符与 C 和 Java 大体一致,Go 语言运算符 | 菜鸟教程 (runoob.com)
Go 拥有和 C++ 类似的指针和地址操作,Java 中是没有的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import "fmt"
func main() { var a int = 4 var b int32 var c float32 var ptr *int
fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a) fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b) fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c)
ptr = &a fmt.Printf("a 的值为 %d\n", a) fmt.Printf("*ptr 为 %d\n", *ptr) a = 6 fmt.Printf("a 的值为 %d\n", a) fmt.Printf("*ptr 为 %d\n", *ptr) }
|
条件语句
Go 支持的if else
语法和Java一致,并且Go中可以不在判断外加小括号
Go 没有三目运算符,所以不支持 ?: 形式的条件判断。
1 2 3 4 5 6 7
| if a < 0 { fmt.Println("a<0") } else if a == 0 { fmt.Println("a=0") } else { fmt.Println("a>0") }
|
switch case末尾不需要加break,这方面Java得检讨
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 30
| package main
import "fmt"
func main() { var grade string var marks int = 90
switch marks { case 90: grade = "A" case 80: grade = "B" default: grade = "D" }
switch { case grade == "A": break fmt.Printf("优秀!\n") fallthrough case grade == "B", grade == "C": fmt.Printf("良好\n") default: fmt.Printf("差\n") } fmt.Printf("你的等级是 %s\n", grade) }
|
type case 用来判断一个变量的类型,x.(type)
只能用在 switch 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import "fmt"
func main() { var x interface{}
switch i := x.(type) { case nil: fmt.Printf(" x 的类型 :%T",i) case int: fmt.Printf("x 是 int 型") case float64: fmt.Printf("x 是 float64 型") case func(int) float64: fmt.Printf("x 是 func(int) 型") case bool, string: fmt.Printf("x 是 bool 或 string 型" ) default: fmt.Printf("未知型") } }
|
select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。
select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。