Golang快速⼊门:从菜鸟到⼤佬
Go代码,但是写着写着,还是容易忘,尤其是再写点Python代码后。所以了⼀篇不错的Golang基础教程,翻译⼀下,时常看看。
你可以在⼯作区⾥随⼼所欲地写代码,Go会在GOPATH或者GOROOT⽬录下搜索包。注:GOROOT是Go的安装路径。
设置GOPATH为你想要的⽬录:
# export 环境变量
export GOPATH=~/workspace
# 进⼊⼯作区⽬录
cd ~/workspace
在⼯作区⽬录⾥创建⽂件。
package main
import (
"fmt"
)
func main(){
fmt.Println("Hello World!")
}
我们使⽤import关键字来引⼊⼀个包。func main是执⾏代码的⼊⼝,fmt是Go的内置包,主要⽤来格式化输⼊/输出。⽽Println是fmt中的⼀个打印函数。
程序,有两种⽅法。
Go是⼀门编译型语⾔,所以在执⾏之前,我们需要先编译它。
> go
go
# Hello World!
Go Go是静态语⾔,因此声明变量时,就会去检查变量的类型。
变量声明有以下三种⽅式。
# 1) a的默认值为0
var a int
# 2) 声明并初始化a,a⾃动赋值为int
var a = 1
# 3) 简写声明
message := "hello world"
字符串类型存储⼀个字节序列。使⽤string关键字来声明。
布尔型使⽤bool声明。
Go还⽀持复数类型数据类型,可以使⽤complex64和complex128进⾏声明。
var a bool = true
var b int = 1
var c string = 'hello world'
var d float32 = 1.222
var x complex128 = cmplx.Sqrt(-5 + 12i)
数组, 分⽚和映射
数组的声明⽅式如下:
var a [5]int
多维数组的声明⽅式如下:
var multiD [2][3]int
Go中的数组有⼀定限制,⽐如不能修改数组长度、不能添加元素、不能获取⼦数组。这时候,更适合使⽤slice[分⽚]这⼀类型。分⽚⽤于存储⼀组元素,允许随时扩展其长度。分⽚的声明类似数组,只是去掉了长度声明。
var b []int
这⾏代码会创建⼀个 0容量、0长度的分⽚。也可以使⽤以下代码设置分⽚的容量和长度。菜鸟教程python函数
// 初始化⼀个长度为5,容量为10的分⽚
numbers := make([]int,5,10)
实际上,分⽚是对数组的抽象。分⽚使⽤数组作为底层结构。⼀个分⽚由三部分组成:容量、长度和指向底层数组的指针。
使⽤append或者copy⽅法可以扩⼤分⽚的容量。append⽅法在分⽚的末尾追加元素,必要时会扩⼤分⽚容量。
numbers = append(numbers, 1, 2, 3, 4)
还可以使⽤copy⽅法来扩⼤容量。
// 创建⼀个更⼤容量的分⽚
number2 := make([]int, 15)
// 把原分⽚复制到新分⽚
copy(number2, number)
如何创建⼀个分⽚的⼦分⽚呢?参考以下代码。
// 创建⼀个长度为4的分⽚
number2 = []int{1,2,3,4}
fmt.Println(numbers) // -> [1 2 3 4]
// 创建⼦分⽚
slice1 := number2[2:]
fmt.Println(slice1) // -> [3 4]
slice2 := number2[:3]
fmt.Println(slice2) // -> [1 2 3]
slice3 := number2[1:4]
fmt.Println(slice3) // -> [2 3 4]
Map也是Go的⼀种数据类型,⽤于记录键值间的映射关系。使⽤以下代码创建⼀个map。
var m map[string]int
// 新增键/值
m['clearity'] = 2
m['simplicity'] = 3
// 打印值
fmt.Println(m['clearity']) // -> 2
fmt.Println(m['simplicity']) // -> 3
这⾥,string,值为int的map变量。
a := 1.1
b := int(a)
fmt.Println(b)
//-> 1
Go中⽤于循环的关键字只有⼀个for。
i := 0
sum := 0
for i < 10 {
sum += 1
i++
}
fmt.Println(sum)
以上代码类似于C语⾔中的while循环。另⼀种循环⽅式如下:
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
Go中的死循环
Go提供了指针,⽤于存储值的地址。指针使⽤*来声明。
var ap *int
这⾥的ap变量即指向整型的指针。使⽤&运算符获取变量地址,*运算符⽤来获取指针所指向的值。
a := 12
ap = &a
fmt.Println(*ap)
// => 12
以下两种情况,通常优先选⽤指针。
把结构体作为参数传递时。因为值传递会耗费更多内存。
声明某类型的⽅法时。传递指针后,⽅法/函数可以直接修改指针所指向的值。
main包中的main函数是go程序执⾏的⼊⼝,除此以外,我们还可以定义其他函数。
func add(a int, b int) int {
c := a + b
return c
}
func main() {
fmt.Println(add(2, 1))
}
//=> 3
如上所⽰,Go中使⽤func关键字加上函数名来定义⼀个函数。函数的参数需要指明数据类型,最后是返回的数据类型。函数的返回值也可以在函数中提前定义:
func add(a int, b int) (c int) {
c = a + b
return
}
func main() {
fmt.Println(add(2, 1))
}
//=> 3
这⾥c被定义为返回值,因此调⽤return语句时,c会被⾃动返回。
Struct
Person类型的数据进⾏分组,那么可以定义⼀个⼈的各种属性,包括姓名,年龄,性别等。
type person struct {
name string
age int
gender string
}
有了Person类型后,现在来创建⼀个 Person对象:
//⽅法 1: 指定参数和值
p = person{name: "Bob", age: 42, gender: "Male"}
//⽅法 2: 仅指定值
person{"Bob", 42, "Male"}
可以使⽤.来获取⼀个对象的参数。
p.name
//=> Bob
p.age
//=> 42
//=> Male
package main
import"fmt"
// 定义结构体
type person struct {
name string
age int
gender string
}
// 定义⽅法
func (p *person) describe() {
fmt.Printf("%v is %v years old.", p.name, p.age)
}
func (p *person) setAge(age int) {
p.age = age
}
func (p person) setName(name string) {
p.name = name
}
func main() {
pp := &person{name: "Bob", age: 42, gender: "Male"}
// 使⽤ . 来调⽤⽅法
pp.describe()
// => Bob is 42 years old
pp.setAge(45)
fmt.Println(pp.age)
//=> 45
pp.setName("Hari")
fmt.Println(pp.name)
//=> Bob
}
注意,此处的接收器是⼀个指针,⽅法中对指针进⾏的任何修改,都可以反映在接收器pp上。这样可以避免复制带来的内存消耗。
age被修改了,⽽name不变。因为只有setAge传⼊的是指针类型,可以对接收器进⾏修改。
在
type animal interface {
description() string
}
animal是⼀个接⼝。通过实现animal接⼝,我们来创建两种不同类型的动物。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论