Skip to content

Latest commit

 

History

History
450 lines (394 loc) · 9.75 KB

5.2.md

File metadata and controls

450 lines (394 loc) · 9.75 KB

go语言快速入门

包与包的引用

在go语言中,每个程序的开头都会有一个包的声明,而这个包的名字,除了main包以外,都要和文件夹的名字相同。在我们引入包时,首先go编译器会在GOROOT下面的src目录下找这个是不是系统定义的,然后如果不是的话,就会去GOPATH下面的src目录下找。比如说之前Hello World程序,引入了一个fmt包。打开GOROOT/src/fmt,就可以看到fmt包的源代码。


这个时候试着自己创建一个包。在GOPATH下的src我先创建一个nladuo的目录,在该目录下创建一个helloworld.go。

// helloworld.go
package nladuo

import (
	"fmt"
)

func PrintHelloWorld() {
	fmt.Println("Hello World")
}

然后把之前的helloworld程序改为下面的这个。

package main

import (
	"nladuo"
)

func main() {
	nladuo.PrintHelloWorld()
}

这样,我们自己的包,就测试成功了。
注意:
1、go语言如果让外部引入包的话,函数名称开头必须大写,如果开头小写的函数只能在当前包内部引用。
2、包引入后,必须使用,如果不使用的话会报错。

package main

import (
	"nladuo"
	"fmt" //不能引用没有使用的包
)

func main() {
	nladuo.PrintHelloWorld()
}

3、“{”不能另起一行(大括号不能另起一行),以下写法会报错:

package main

import (
	"nladuo"
)

func main()
{ //不能另起一行
	nladuo.PrintHelloWorld()
}

常见命令

go run 命令:直接编译并运行go文件。
go build命令:编译go文件,比如说使用go build helloworld.go之后,就会生成一个helloworld.exe文件。
go install命令:编译go文件,然后会放到GOBIN目录下,如果GOBIN在PATH里面的话,可以在任何一个地方运行自己的程序。
go doc命令:go语言的文档。比如要查看fmt包的Println函数,你可以输入一下命令。

go doc fmt.Println

除此之外,你还可以使用godoc(中间没空格)工具在网页上显示文档。

godoc -http=:8000

在浏览器上输入:127.0.0.1:8000,就可以看到完全的文档了。

更多详细用法,可以直接输入go查看go语言的其它命令,使用go help查看详细用法。
输入go查看全部命令:

输入go help run查看go run命令的帮助:

变量

package main

import (
	"fmt"
)

var str1 string = "str1" //声明全局变量
//str2 string := "str2" 不能这么声明全局变量
var ( //声明多个全局变量
	str2 string = "str2"
	str3 string = "str3"
)

func main() {
	var num1 int = 1 //声明局部变量
	var num2 = 2     //如果声明时可以确定类型 ,可以不写变量类型
	//var num3 		 不能确定类型, 必须加上类型
	var num3 int
	num3 = 3
	num4 := 4        //简易声明局部变量
	fmt.Println(str1, str2, str3, num1, num2, num3, num4)
}

注意:不能有未使用的变量,在别的语言中,有未使用的变量会有警告,在go语言中会导致编译不通过。

条件判断

go语言和类c语言的差不多,不过不需要加括号

package main

import (
	"fmt"
)

func main() {
	a := 1
	b := 2
	if a > b {
		fmt.Println("a > b")
	} else if a == b {
		fmt.Println("a == b")
	} else {
		fmt.Println("a < b")
	}
}

另外,go语言还可以在if语句中进行初始化:

package main

import (
	"fmt"
)

func main() {
	if a := 1; a == 1 { //先初始化a为1,再进行判断
		fmt.Println("a == 1")
	}
}

循环

普通的for循环:

package main

import (
	"fmt"
)

func main() {
	for i := 0; i < 10; i++ {
		fmt.Print(i, " ")
	}
	fmt.Println()
}

go语言的“while”循环

package main

import (
	"fmt"
)

func main() {
	i := 0
	for i < 10 { //也用for
		fmt.Print(i, " ")
		i++
	}
	fmt.Println()
}

死循环:

package main

import (
	"fmt"
	"time"
)

func main() {
	i := 0
	for {              //每两秒打印一个数
		fmt.Println(i)
		i++
		time.Sleep(2 * time.Second) //程序休眠2秒
	}
}

函数

定义一个普通的函数:

package main

import (
	"fmt"
)

func myprint(v interface{}) { //go语言中interface{}可以代表任何类型,可以当成java中的Object类型
	fmt.Println(v)
}

func main() {
	myprint(100)
	myprint("Hello World")
}

带多返回值的函数:

package main

import (
	"fmt"
)

func swap(a int, b int) (int, int) {
	return b, a
}

func main() {
	a := 1
	b := 2
	fmt.Println("a =", a, "b =", b)
	a, b = swap(a, b)
	fmt.Println("a =", a, "b =", b)
}

方法

package main

import (
	"fmt"
)

type MyInt int

func (this MyInt) getVal() int {
	return int(this)
}

func main() {
	var myInt MyInt = MyInt(1)
	fmt.Println(myInt.getVal())
}

定义一个结构体,并添加String方法。

package main

import (
	"fmt"
	"strconv"
)

type Person struct {
	Name string
	Age  int64
}

func (this Person) String() string { //类似java的toString方法
	ageStr := strconv.FormatInt(this.Age, 10)
	return "名字:" + this.Name + " 年龄:" + ageStr
}

func main() {
	p := Person{Name: "nladuo", Age: 20}
	fmt.Println(p) //不需要写fmt.Println(p.String())
}

有关指针的使用:

package main

import (
	"fmt"
	"strconv"
)

type Person struct {
	Name string
	Age  int64
}

func (this Person) String() string { //类似java的toString方法
	ageStr := strconv.FormatInt(this.Age, 10) //把int转换为string类型,第二个参数代表按照10进制转换
	return "名字:" + this.Name + " 年龄:" + ageStr
}

func (this Person) ChangeName1(name string) {
	this.Name = name
}

func (this *Person) ChangeName2(name string) {
	this.Name = name
}

func main() {
	p := Person{Name: "nladuo", Age: 20}
	fmt.Println(p)
	p.ChangeName1("Kalen Blue")
	fmt.Println(p) //没有改变name
	p.ChangeName2("Kalen Blue")
	fmt.Println(p) //name 发生改变
}

通过指针的这个例子,可以知道,如果需要改变struct内部的值,就需要使用指针,而不使用指针的话,则相当于完全拷贝了一份,相比指针,一是不能改变变量的值,二是浪费储存空间。

一些类型

介绍go语言的数组、切片以及Map

数组

数组的创建和遍历

package main

import (
	"fmt"
)

func main() {
	arr := [5]int{1, 2, 3, 4, 5}
	//遍历数组方式1
	for i := 0; i < len(arr); i++ {
		fmt.Print(i, " ")
	}
	fmt.Println()
	//遍历数组方式2
	for v := range arr {
		fmt.Print(v, " ")
	}
	fmt.Println()
	//遍历数组方式2,并获取索引
	for k, v := range arr {
		fmt.Println("index:", k, " value:", v)
	}
	fmt.Println()
}

go语言的数组和c语言的数组差不多,一旦声明,就无法改变长度了。所以我们更多用的是切片。

切片

数组和切片声明上的不同。

arr := [5]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}

另一种声明方式,通过make来实现。make的第二个参数和第三个是声明slice的长度和容量。 其实是因为切片就是数组的一个引用,内部其实也指向一个数组,比如说下面的这个,内部指向一个长为5的底层数组,这个切片本身并没有元素。等到数组的容量不够的时候,go语言内部会帮助我我们修改底层数组的大小。

package main

import (
	"fmt"
)

func main() {
	slice := make([]int, 0, 5) //0是slice的长度,5代表slice的容量
	fmt.Println("len:", len(slice))
	fmt.Println("cap:", cap(slice))
}

切片的一些操作。

package main

import (
	"fmt"
)

func printSlice(tag string, slice []int) {
	fmt.Print(tag, " ")
	for _, v := range slice {//一个下划线代表不关心索引的取值
		fmt.Print(v, " ")
	}
	fmt.Println()
}

func main() {
	var slice []int
	fmt.Println("len:", len(slice))
	fmt.Println("cap:", cap(slice))
	for i := 0; i < 10; i++ {
		slice = append(slice, i) //添加元素
	}
	printSlice("添加元素:", slice)
	fmt.Println("len:", len(slice))
	fmt.Println("cap:", cap(slice))
	//添加切片,通用方式:slice1=append(slice1, slice2...)
	slice = append(slice, []int{10, 11, 12, 13, 14, 15}...)
	printSlice("添加切片:", slice)
	fmt.Println("len:", len(slice))
	fmt.Println("cap:", cap(slice))
	printSlice("添加切片:", slice)
	printSlice("slice[:3]:", slice[:3])     //slice[0]到slice[3]
	printSlice("slice[4:]:", slice[4:])     //slice[4+1]到末尾
	printSlice("slice[3:10]:", slice[3:10]) //slice[3+1]到slice[10]
	printSlice("slice[:]:", slice[:])       //整个slice
	//删除第3个元素
	//通用方式,slice=append(slice[:i], slice[i+1:]...)
	slice = append(slice[:3], slice[4:]...)
	printSlice("删除第3个元素:", slice)

}

Map

map其实就是相当于哈希表或者叫字典,直接看看它的用法

package main

import (
	"fmt"
)

func printMap(m map[string]string) {
	for k, v := range m {
		fmt.Println("key:", k, "  value:", v)
	}
	fmt.Println()
}
func main() {
	var lans map[string]string
	lans = make(map[string]string) //必须使用make来初始化
	//也可以直接使用  lans := make(map[string]string)
	lans["go"] = "谷歌公司" //添加元素
	lans["swift"] = "苹果公司"
	lans["java"] = "Oracle公司"
	printMap(lans)
	//判断key是否存在
	if v, ok := lans["java"]; ok {
		fmt.Println("存在key:java 属于", v, "\n")
	} else {
		fmt.Println("不存在key:java", "\n")
	}
	delete(lans, "java") //删除元素
	printMap(lans)
	//判断key是否存在
	if v, ok := lans["java"]; ok {
		fmt.Println("存在key:java 属于", v, "\n")
	} else {
		fmt.Println("不存在key:java", "\n")
	}
}

链接