只在此山中,雲深不知處
Basic
根據hello world的例子,可以看出go的語法是:
Package Declaration: 定義package(e.g. main),這行指令一定要做。
Import Packages: 導入package(e.g. fmt ),讓compiler知道要納入在fmt這個package內的檔案。
functions: 定義函數,而main()這個函數是程式開始的點。
Statements and Expressions: 程式指令,e.g. fmt.Println("Hello, World!")是使用fmt裡面的Println函數來印出字串(請注意P要大寫而且指令最後沒有分號)。
Go的註解方式與Java和C++相同,單行為//,段落為/**/ 。
命名時使用英文字母、底線(_)與數字(數字不可在前),不要使用標點(e.g. ,;:)、符號(e.g. @$%)與空白 。
也不可以使用關鍵字(keywords)命名,Go的關鍵字列表如下:
break
default
func
interface
select
case
defer
Go
map
Struct
chan
else
Goto
package
Switch
const
fallthrough
if
range
Type
continue
for
import
return
Var
使用fmt.Println()來印出資訊(不同類型資訊使用逗點分隔),或使用fmt.Printf()來印出格式化資訊,Printf()常用的格式如下:。
%v: value in default format
%s: string
%b: base 2, decimalless scientific notation with exponent a power of two, e.g. 123345p-77
%d: int, int8, etc.(base 10)
%o: base 8
%x: base 16, lower-case, two characters per bytw
%t: bool
%g: float32, complex64, etc.(for large exponents)
%p: pointer
%f: decimal point(can specify the width, e.g. %9f, %.2f, %9.2f, %9.f)
%e: scientific notation, e.g. 123e+88
%%: literal percent sign
Data Types & Variables
Go中的資料型態可區分為如下:
Boolean: true & false。
Numeric: integer & floating point values。
uint8(byte): 8-bit >> 0~255(u stands for unsigned)。
uint16: 16-bit >> 0~65535(u stands for unsigned)。
uint32: 32-bit >> 0~4294967295(u stands for unsigned)。
uint64: 64-bit >> 0~18446744073709551615(u stands for unsigned)。
int8: 8-bit >> -128~127。
int16: 16-bit >> -32768~32767。
int32(rune): 32-bit >> -2147483648~2147483647。
int64: 64-bit >> -9223372036854775808~9223372036854775807。
float32: 32-bit。
float64: 64-bit。
complex64: complex number >> float32 real and imaginary parts。
complex128: complex number >> float64 real and imaginary parts。
String: 字串。
Derived: 此型態包含Pointer, Array, Structure, Union, Function, Slice, Interface, Map & Channel。
變數的宣告(宣告時若使用byte, int, float32為基本型態,使用預設長度):
宣告變數可以使用以下兩種方式:
需使用關鍵字var來宣告。
var yourAge int: 宣告變數名為yourAge,型態是int。
var hisAge = 18.5: 宣告變數名為hisAge,型態由給定初值決定,在此為float(可使用:=來省略var關鍵字)。
使用fmt.Printf("%T", variable)來得到變數型態。
宣告變數時,可以使用小括號將其一併包含,例如:
如果有多個package要import也可以如此處理,e.g.
使用const關鍵字用來定義常數。
使用\符號來定義溢出字(Escape sequence)。
可用的escape sequence與C++差不多:\\, \", \?, \a, \b, \f, \n, \r, \t, \v, \ooo, \xhh。
Operators
Go的運算子包括Arithmetic, Relational, Logical, Bitwise, Assignment, & Miscellaneous:
Arithmetic Operators: +, -, *, /, %, ++, -- 。
使用float32(a)將a cast成為float32。
++加1,--減1。
Relational Operators: ==, !=, >, <, >=, <= 。
Logical Operators: &&, ||, ! 。
Bitwise Operators: &, |, ^, <<, >> 。
Assignment Operators: =, +=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |= 。
Miscellaneous Operators: &, * 。
&表示變數記憶體位址,*表示指向某記憶體位址之pointer。
Precedence指的是運算的先後順序,原則上與其他語言相同。
() [] -> . ++ --
+ - ! ~ ++ - - (type)* & sizeof
* / %
+ -
<< >>
< <= > >=
== !=
&
^
|
&&
||
?:
= += -= *= /= %=>>= <<= &= ^= |=
,
Flow Control
包含if...else..., switch, select, for loop and functions。
: if...else...
Nested-if-else
switch
如果switch之後接變數(int),則使用變數值來判斷使用哪一個case。
如果swithc之後沒有變數,則case使用bool來判斷。
與其他語言不同處是不需要break。
Type switch。
判斷Type,switch後的變數必須為interface{}型態(可以給初值)。
select與switch類似,只適用於選擇communication channel operation。
chan關鍵字用來定義channel,channel於之後討論。
Go只有一種loop,也就是for loop,其語法如下:
Pointers
與C++類似,Go可以使用pointers。
: 使用&符號取得變數位址(pointer),使用*符號來dereference一個pointer。
package main
import (
"fmt"
)
func main() {
a:=20
var ip* int
var pip** int
fmt.Printf("Value of *ip: %v\n", ip)
fmt.Printf("Value of **pip: %v\n", pip)
ip = &a // ip point to the address of a
pip = &ip // pip point to the address of ip
fmt.Println("Address of a:", &a)
fmt.Printf("Address stored in ip: %x\n", ip)
fmt.Printf("Value of *ip: %v\n", *ip)
if(ip==nil){
fmt.Println("ip is nil")
}else{
fmt.Println("ip is not nil")
}
fmt.Println("Address of pip:", pip)
fmt.Println("Address of ip:", *pip)
fmt.Println("Value of **pip:", **pip)
}
使用*符號來宣告變數為pointer,若是沒有給初始值,pointer指向。
使用**符號來宣告變數為pointer的位址(pointer的pointer),若是沒有給初始值,一樣指向。
使用*符號來dereference,所以*ip為a的值,*pip為ip的address,**pip為*ip(也就是a)。
: 在設計函數時,可以傳遞Pointers當作arguments。
package main
import (
"fmt"
"math"
)
func circleArea(radius *float64) float64{
return math.Pi*(*radius)*(*radius)
}
func main() {
r:=10.0
fmt.Printf("Area:%g", circleArea(&r))
}