“容器”类型
数组(列表)、切片(Slice)
package main import "fmt" func main() { // initialized array var numbers [5]int // becomes [0, 0, 0, 0, 0] // change one of them numbers[2] = 100 // create a new slice from an array some_numbers := numbers[1:3] fmt.Println(some_numbers) // [0, 100] // length of it fmt.Println(len(numbers)) // initialize a slice var scores []float64 scores = append(scores, 1.1) // recreate to append scores[0] = 2.2 // change your mind fmt.Println(scores) // prints [2.2] // when you don't know for sure how much you're going // to put in it, one way is to var things [100]string things[0] = "Peter" things[1] = "Anders" fmt.Println(len(things)) // 100 }
对比Python:
# initialize list numbers = [0] * 5 # change one of them numbers[2] = 100 some_numbers = numbers[1:3] print(some_numbers) # [0, 100] # length of it print(len(numbers)) # 5 # initialize another scores = [] scores.append(1.1) scores[0] = 2.2 print(scores) # [2.2]
范围(Range)
package main import "fmt" func main() { names := []string{ "Hann", "Yang", "Hann Yang", } for i, name := range names { fmt.Printf("%d. %s\n", i+1, name) } }
对比Python:
names = ["Hann", "Yang", "Hann Yang"] for i,name in enumerate(names): print(f'{i+1}. {name}')
Map(集合)
package main import "fmt" func main() { elements := make(map[string]int) elements["H"] = 1 fmt.Println(elements["H"]) // remove by key elements["O"] = 8 delete(elements, "O") // only do something with a element if it's in the map if number, ok := elements["O"]; ok { fmt.Println(number) // won't be printed } if number, ok := elements["H"]; ok { fmt.Println(number) // 1 } }
对比Python:
elements = {} elements["H"] = 1 print(elements["H"]) # 1 # remove by key elements["O"] = 8 elements.pop("O") # do something depending on the being there if "O" in elements: print(elements["O"]) if "H" in elements: print(elements["H"])
函数 func
函数是基本的代码块,用于执行一个任务。
Go 语言最少有个 main() 函数。
你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。
函数声明告诉了编译器函数的名称,返回类型,和参数。
Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回数组中包含的元素个数。
函数定义
Go 语言函数定义格式如下:
func function_name( [parameter list] ) [return_types] { 函数体 }
定义解析:
func:函数由 func 开始声明
function_name:函数名称,参数列表和返回值类型构成了函数签名。
parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
函数体:函数定义的代码集合。
Go的函数用func起头,函数体和C/C++一样用{}包括代码,但代码语句不用“ ; ”表示结束。
与Python的比较:def funcname(): 起头的关键字不一样,python不用{}括号但要用“ : ”;以及有强制而严格的缩进。
函数调用
当创建函数时,定义的函数需要做什么,通过调用该函数来执行指定任务。
调用函数,可以向函数传递参数,并返回值:
package main import "fmt" func main() { /* 定义局部变量 */ var a int = 100 var b int = 200 var ret int /* 调用函数并返回最大值 */ ret = max(a, b) fmt.Printf( "最大值是 : %d\n", ret ) } /* 函数返回两个数的最大值 */ func max(num1, num2 int) int { /* 定义局部变量 */ var result int if (num1 > num2) { result = num1 } else { result = num2 } return result }
对比Python:
def Max(n1,n2): if n1>n2: return n1 return n2 a,b = 100,200 print(Max(a,b))
多个返回值
package main import "fmt" func swap(x, y int) (int, int) { return y, x } func main() { a, b := swap(3, 23) fmt.Println(a, b) }
对比Python: 即返回值是一个元组tuple()
def Swap(n1,n2): return n2,n1 a,b = 100,200 a,b = Swap(a,b) print(a, b)
递归函数
递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。递归函数必须有结束条件。
递归实例
实例1:阶乘
package main import "fmt" func Factorial(n uint64)(result uint64) { if (n > 0) { result = n * Factorial(n-1) return result } return 1 } func main() { var i int = 15 fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(uint64(i))) }
实例2:斐波那契数列
package main import "fmt" func fibonacci(n int) int { if n == 1 || n == 2 { return 1 } return fibonacci(n-2) + fibonacci(n-1) } func main() { var i int for i = 1; i <= 10; i++ { fmt.Printf("%d\t", fibonacci(i)) } }
Python这两个函数练得太多了,略。
字面函数(内联函数、函数嵌套)
暂且不知道叫什么,姑且这么称呼吧。
package main import "fmt" func main() { number := 0 increment := func(amount int) { number += amount } increment(1) increment(2) increment(5) fmt.Println(number) // 8 }
对比Python:
def run(): def increment(amount): return number + amount number = 0 number = increment(1) number = increment(2) number = increment(5) print(number) # 8 run()
字面函数,形式上有点像Python,C/C++的匿名函数,或称lambda表达式。
package main import "fmt" func main() { Add := func(a, b int) int { return a + b } fmt.Printf("Add function literals: %d\n", Add(10, 2)) }
内置函数
内置函数是不需要引入包直接可用的函数。
append --向数组,slice里添加元素,返回新的数组,slice
delete --删除map里对应key的value值
close --关闭通道
copy --用于复制和连接slice,返回复制的数目
imag -- 返回complex的实部
real -- 返回complex的虚部
new -- 分配内存,主要用来分配值类型如int,struct,返回指向type的指针
make -- 分配内存,返回type本身(只用于slice,map,chan)
painc -- 抛出异常,与recover连用
recover -- 捕获异常
cap -- 容量,容积capacity
len -- 长度,比如string、array、slice、map、channel
常用包
fmt 标准包
math 数学运算包
errors 错误工具包
string 字符串操作包
strconv 字符串转换包
regexp 正则包(golang的正则实现的RE2标准)
encoding/json json转换工具包
os 文件读写操作
time 定时器、时间相关包
net 网络相关包
time包
常量
const ( Nanosecond Duration = 1 Microsecond = 1000 * Nanosecond Millisecond = 1000 * Microsecond Second = 1000 * Millisecond Minute = 60 * Second Hour = 60 * Minute )
实例
package main import ( "fmt" "time" ) func main() { t0 := time.Now() time.Sleep(3*time.Second + 230*time.Millisecond) elapsed := time.Since(t0) fmt.Printf("Took %s", elapsed) }
对比Python:
import time t0 = time.time() time.sleep(3.23) # for example t1 = time.time() print("Took {:.2f} seconds".format(t1 - t0))
math包
常量
E = 2.71828182845904523536028747135266249775724709369995957496696763 Pi = 3.14159265358979323846264338327950288419716939937510582097494459 Phi = 1.61803398874989484820458683436563811772030917980576286213544862 Sqrt2 = 1.41421356237309504880168872420969807856967187537694807317667974 SqrtE = 1.64872127070012814684865078781416357165377610071014801157507931 SqrtPi = 1.77245385090551602729816748334114518279754945612238712821380779 SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 Ln2 = 0.693147180559945309417232121458176568075500134360255254120680009 Log2E = 1 / Ln2 Ln10 = 2.30258509299404568401799145468436420760110148862877297603332790 Log10E = 1 / Ln10 MaxFloat32 = 3.40282346638528859811704183484516925440e+38 // 2**127 * (2**24 - 1) / 2**23 SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 23) MaxFloat64 = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52 SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 52)
极值
MaxInt8 = 1<<7 - 1 MinInt8 = -1 << 7 MaxInt16 = 1<<15 - 1 MinInt16 = -1 << 15 MaxInt32 = 1<<31 - 1 MinInt32 = -1 << 31 MaxInt64 = 1<<63 - 1 MinInt64 = -1 << 63 MaxUint8 = 1<<8 - 1 MaxUint16 = 1<<16 - 1 MaxUint32 = 1<<32 - 1 MaxUint64 = 1<<64 - 1
常用数学函数
/*IsNaN函数 func IsNaN(f float64) (is bool) 报告f是否表示一个NaN(Not A Number) */ func testIsNaN() { fmt.Println(math.IsNaN(12321.321321)) //false } /*Ceil函数 func Ceil(x float64) float64 返回一个不小于x的最小整数,简单来说就是向上取整 */ func testCeil() { fmt.Println(math.Ceil(1.13456)) //2 } /*Floor函数 func Floor(x float64) float64 返回一个不大于x的最小整数,简单来说就是向下取整 */ func testFloor() { fmt.Println(math.Floor(2.9999)) //2 } /*Trunc函数 func Trunc(x float64) float64 返回x整数部分,与Floor一样 */ func testTrunc() { fmt.Println(math.Trunc(2.9999)) //2 } /*Abs函数 func Abs(x float64) float64 返回x的绝对值 */ func testAbs() { fmt.Println(math.Abs(-2.999)) //2.999 } /*Max函数 func Max(x, y float64) float64 返回x和y中最大值 */ func testMax() { fmt.Println(math.Max(1000,200)) //1000 } /*Min函数 func Min(x, y float64) float64 返回x和y中最小值 */ func testMin() { fmt.Println(math.Min(1000,200)) //200 } /*Dim函数 func Dim(x, y float64) float64 函数返回x-y和0中的最大值 */ func testDim() { fmt.Println(math.Dim(1000,2000)) //0 fmt.Println(math.Dim(1000,200)) //800 } /*Mod函数 func Mod(x, y float64) float64 取余运算,可以理解为 x-Trunc(x/y)*y,结果的正负号和x相同 */ func testMod() { fmt.Println(math.Mod(123,0)) //NaN fmt.Println(math.Mod(123,10)) //3 } /*Sqrt函数 func Sqrt(x float64) float64 返回x的二次方根,平方根 */ func testSqrt() { fmt.Println(math.Sqrt(144)) //12 } /*Cbrt函数 func Cbrt(x float64) float64 返回x的二次方根,平方根 */ func testCbrt() { fmt.Println(math.Cbrt(1728)) //12 } /*Hypot函数 func Hypot(p, q float64) float64 返回Sqrt(p*p+q*q),相当于求直角三角形的斜边长 */ func testHypot() { fmt.Println(math.Hypot(3,4)) //5 } /*Pow函数 func Pow(x, y float64) float64 求幂,x的y次方 */ func testPow() { fmt.Println(math.Pow(2,3)) //8 } /*Sin函数 func Sin(x float64) float64 求正弦 */ func testSin() { fmt.Println(math.Sin(12)) //-0.5365729180004349 } /*Cos函数 func Cos(x float64) float64 求余弦 */ func testCos() { fmt.Println(math.Cos(12)) //0.8438539587324921 } /*Tan函数 func Tan(x float64) float64 求正切 */ func testTan() { fmt.Println(math.Tan(12)) //-0.6358599286615807 } /*Log函数 func Log(x float64) float64 求自然对数 */ func testLog() { fmt.Println(math.Log(2)) //0.6931471805599453 } /*Log2函数 func Log2(x float64) float64 求2为底的对数 */ func testLog2() { fmt.Println(math.Log2(128)) //7 } /*Log10函数 func Log10(x float64) float64 求10为底的对数 */ func testLog10() { fmt.Println(math.Log10(10000)) //4 } /*Signbit函数 func Signbit(x float64) bool 如果x是一个负数或者负零,返回真 */ func testSignbit() { fmt.Println(math.Signbit(10000)) //false fmt.Println(math.Signbit(-200)) //true }
实例
package main import ( "fmt" "math" ) func main() { var x float64 var n int fmt.Scanf("%f%d", &x, &n) fmt.Println(powerf(x, n)) fmt.Println(powerf2(x, n)) fmt.Println(powerf3(x, n)) fmt.Println(math.Pow(x, float64(n))) } //二分法 func powerf(x float64, n int) float64 { ans := 1.0 for n != 0 { if n%2 == 1 { ans *= x } x *= x n /= 2 } return ans } //递归法 func powerf2(x float64, n int) float64 { if n == 0 { return 1 } else { return x * powerf2(x, n-1) } } //循环法 func powerf3(x float64, n int) float64 { ans := 1.0 for n != 0 { ans *= x n-- } return ans }
本篇学到这里暂告一段落,以上内容都能领会的话,常见的小问题简单的入门基础题基本上都能解决了; Go语言还有很多高级内容,拟列入Golang进阶之路中......