package main
import (
"fmt"
)
func main() {
//if
/*
x := 5
if x > 10 {
fmt.Println("X is larger than 10")
} else {
fmt.Println("X is smaller than 10")
}
//也可写成
//if y := GetSomeNumber(); y < 10 {
//}
*/
//goto 用goto跳转到必须在当前函数内定义的标签(以冒号结束作为标签,且大小写敏感)
/*
i := 0
Here:
fmt.Println(i)
i++
goto Here
*/
//for 和其他语言的for一样,但他可以当作while来使用,也可配合range 读取slice,map数据
/*
//for=while
sum := 0
for sum < 100 {
sum++
}
//for range map(slice)
for k,v=range map{
fmt.Println("map's key :",k)
fmt.Println("map's value:",v)
}
//如果没有fmt.Println("map's key :",k)这句,使用k申明了而没使用,会造成编译出错
//所以,要做修改将k改成_,来丢弃不需要的返回值
for k,v=range map{
fmt.Println("map's key :",k)
fmt.Println("map's value:",v)
}
//修改成
for _,v=range map{
fmt.Println("map's value:",v)
}
*/
//switch,如果swith 没有表达式,它会匹配true;每个case后面不用加break;
//它默认加了break,如果要实现没有break的情况,要在除default外的所有case后面加fallthrough
/*
i := 5
switch i {
case 1:
fmt.Println("i is equal to 1")
case 2:
fmt.Println("i is equal to 2")
case 3, 4, 5, 6:
fmt.Println("i is equal to 3,4,5 or 6")
fallthrough //添加后,相当于去掉默认的break
default:
fmt.Println("others")
}
*/
//函数
/*
func funcName(input1 type1,input2 type2)(output1 type1,output2 type2)
{
//返回多个值
return value1,value2
}
//上面返回值声明了两个变量output1和output2,
//如果你不想声明也可以,直接就两个类型
func funcName(input1 type1,input2 type2)(type1,type2)
{
//返回多个值
return value1,value2
}
//如果只有一个返回值且不声明返回值变量,那么你可以省略 包括返回值 的括号
func funcName(input1 type1,input2 type2) type1
{
//返回1个值,可省略返回值的名称和括号
return value1+value2
}
//如果没有返回值,那么就直接省略最后的返回信息
func funcName(input1 type1,input2 type2)
{
//没有返回值,可省略返回信息
sum:= value1+value2
}
//如果参数类型相同,则可以省略第一个参数的类型
//说明input1和input2都是参数都是int类型的
func funcName(input1 ,input2 int)
{
//有返回值,return必须写在最外层
return value1+value2
}
//变参,参数类型为int,个数不限
func funcName(arg ...int) {
}
//示例
var var1 int32 = 2
var var2 int32 = 5
var3, var4 := PlusAndTimes(var1, var2)
fmt.Printf("%d,%d", var3, var4)
*/
//传值与传指针
//传指针使得多个函数能操作同一个对象。
//传指针比较轻量级 (8bytes),只是传内存地址,
//我们可以用指针传递体积大的结构体。
//如果用参数值传递的话, 在每次copy上面就会花费相对较多的系统开销(内存和时间)。
//所以当你要传递大的结构体的时候,用指针是一个明智的选择。
//Go语言中string,slice,map这三种类型的实现机制类似指针,
//所以可以直接传递,而不用取地址后传递指针。
//(注:若函数需改变slice的长度,则仍需要取地址传递指针)
//传值,传指针示例
/*
x := 3
fmt.Println("x = ", x) // 应该输出 "x = 3"
x1 := addByValue(x) //调用add1(x)
fmt.Println("x+1 = ", x1) // 应该输出"x+1 = 4"
fmt.Println("x = ", x) // 应该输出"x = 3"
fmt.Println("------------")
//传指针
fmt.Println("x = ", x) // 应该输出 "x = 3"
x2 := addByPoint(&x) //调用add1(x)
fmt.Println("x+1 = ", x2) // 应该输出"x+1 = 4"
fmt.Println("x = ", x) // 应该输出"x = 4"
*/
//defer
//Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。
//当函数执行到最后时,这些defer语句会按照【逆序】执行,最后该函数返回
//见示例
//函数作为值、类型
//Go中函数也是一种变量,我们可以通过type来定义它,
//它的类型就是所有拥有相同的参数,相同的返回值的一种类型
//类似于c#中的委托
//示例
slice := []int{1, 2, 3, 4, 5, 7}
fmt.Println("slice = ", slice)
odd := filter(slice, isOdd) // 函数当做值来传递了
fmt.Println("Odd elements of slice are: ", odd)
even := filter(slice, isEven) // 函数当做值来传递了
fmt.Println("Even elements of slice are: ", even)
//Panic和Recover
//Panic:当函数F调用panic,函数F的执行被中断,
//但是F中的延迟函数会正常执行,然后F返回到调用它的地方。
//Recover:仅在延迟函数中有效。
//在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。
//main函数和init函数
//每个package中的init函数都是可选的,
//但package main就必须包含一个main函数。
//执行顺序
//初始化和执行main包-->导入其他包(如果main包导入了其他包)-->初始化其他包的常量、变量
//-->执行其他包的init()-->初始化main包的变量、常量-->执行main包的init()-->执行main()
}
func PlusAndTimes(var1, var2 int32) (plusVar, timesVar int32) {
plusVar = var1 + var2
timesVar = var1 * var2
return
}
//简单的一个函数,实现了参数+1的操作
func addByValue(a int) int {
a = a + 1 // 我们改变了a的值
return a //返回一个新值
}
//简单的一个函数,实现了参数+1的操作
func addByPoint(a *int) int {
*a = *a + 1
return *a
}
//defer Demo
/*
func testNoDefer() bool {
file.open("file")
if failureX {
file.close()
return false
}
if failureY {
file.close()
return false
}
file.close()
return true
}
func testDefer() bool{
file.opern()
defer file.close()
if failureX {
return false
}
if failureY {
return false
}
return true
}
*/
//声明一个函数类型(类型于c#中的委托),isOdd和isEven的参数和返回值必须和testInt一样
type testInt func(intVar int) bool
func isOdd(integer int) bool {
if integer%2 == 0 {
return true
}
return false
}
func isEven(integer int) bool {
if integer%2 == 0 {
return false
}
return true
}
func filter(slice []int, f testInt) []int {
var result []int
for _, value := range slice {
if f(value) {
result = append(result, value)
}
}
return result
}