包
package main
//导入包
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
函数
package main
import "fmt"
//函数常规定义
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
package main
import "fmt"
//当连续两个或多个函数的已命名形参类型相同时,除最后一个类型以外,其它都可以省略。
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
package main
import "fmt"
//$$函数可以返回任意数量的返回值
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
package main
import "fmt"
//Go 的返回值可被命名,它们会被视作定义在函数顶部的变量。这里x, y是返回值
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return //没有参数的 return 语句返回已命名的返回值。也就是 直接 返回。
}
func main() {
fmt.Println(split(17))
}
变量
package main
import "fmt"
//var 语句可以出现在包或函数级别
//全局变量
var c, python, java bool
func main() {
var i int
fmt.Println(i, c, python, java)
}
package main
import "fmt"
//变量声明可以包含初始值,每个变量对应一个。
var i, j int = 1, 2
func main() {
//如果初始化值已存在,则可以省略类型;变量会从初始值中获得类型。
var c, python, java = true, false, "no!"
fmt.Println(i, j, c, python, java)
}
package main
import "fmt"
//$$注意:函数外的每个语句都必须以关键字开始(var, func 等等),因此 := 结构不能在函数外使用。
func main() {
var i, j int = 1, 2
//在函数中,简洁赋值语句 := 可在类型明确的地方代替 var 声明
k := 3
c, python, java := true, false, "no!"
fmt.Println(i, j, k, c, python, java)
}
基本类型
package main
import (
"fmt"
"math/cmplx"
)
/**
数据类型:
bool
string 注意字符串是一个基本类型
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 的别名
rune // int32 的别名
// 表示一个 Unicode 码点
float32 float64
complex64 complex128
注意:int, uint 和 uintptr 在 32 位系统上通常为 32 位宽,在 64 位系统上则为 64 位宽。
**/
var (
ToBe bool = false
MaxInt uint64 = 1 cap(slice) { // if necessary, reallocate
// allocate double what's needed, for future growth.
newSlice := make([]byte, (n+1)*2)
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:n]
copy(slice[m:n], data)
return slice
}
下面是 AppendByte 的一种用法:
p := []byte{2, 3, 5}
p = AppendByte(p, 7, 11, 13)
// p == []byte{2, 3, 5, 7, 11, 13}
类似 AppendByte 的函数比较实用,因为它提供了切片容量增长的完全控制。 根据程序的特点,可能希望分配较小的活较大的块,或则是超过某个大小再分配。但大多数程序不需要完全的控制,因此Go提供了一个内置函数 append , 用于大多数场合;它的函数签名:
func append(s []T, x ...T) []T
append 函数将 x 追加到切片 s 的末尾,并且在必要的时候增加容量。
a := make([]int, 1)
// a == []int{0}
a = append(a, 1, 2, 3)
// a == []int{0, 1, 2, 3}
如果是要将一个切片追加到另一个切片尾部,需要使用 ... 语法将第2个参数展开为参数列表。
a := []string{"John", "Paul"}
b := []string{"George", "Ringo", "Pete"}
a = append(a, b...) // equivalent to "append(a, b[0], b[1], b[2])"
// a == []string{"John", "Paul", "George", "Ringo", "Pete"}
由于切片的零值 nil 用起来就像一个长度为零的切片,我们可以声明一个切片变量然后在循环 中向它追加数据:
// Filter returns a new slice holding only
// the elements of s that satisfy fn()
func Filter(s []int, fn func(int) bool) []int {
var p []int // == nil
for _, v := range s {
if fn(v) {
p = append(p, v)
}
}
return p
}
可能的“陷阱”
正如前面所说,切片操作并不会复制底层的数组。整个数组将被保存在内存中,直到它不再被引用。 有时候可能会因为一个小的内存引用导致保存所有的数据。例如, FindDigits 函数加载整个文件到内存,然后搜索第一个连续的数字,最后结果以切片方式返回。
var digitRegexp = regexp.MustCompile("[0-9]+")
func FindDigits(filename string) []byte {
b, _ := ioutil.ReadFile(filename)
return digitRegexp.Find(b)
}
这段代码的行为和描述类似,返回的 []byte 指向保存整个文件的数组。因为切片引用了原始的数组, 导致 GC 不能释放数组的空间;只用到少数几个字节却导致整个文件的内容都一直保存在内存里。要修复整个问题,可以将感兴趣的数据复制到一个新的切片中:
func CopyDigits(filename string) []byte {
b, _ := ioutil.ReadFile(filename)
b = digitRegexp.Find(b)
c := make([]byte, len(b))
copy(c, b)
return c
}
Range
package main
import "fmt"
/**
for 循环的 range 形式可遍历切片或映射。
当使用 for 循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。
**/
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
package main
import "fmt"
/**
可以将下标或值赋予 _ 来忽略它。
for i, _ := range pow
for _, value := range pow
若你只需要索引,忽略第二个变量即可。
for i := range pow
**/
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?