go语言的学习------控制结构与函数

控制结构

  • Go完全忽略了if switch 和 for 结构中的括号,看起来更加简洁一点
  • 可以使用return来结束函数的执行,使用goto与标签来调整执行的位置
  • runtime.GOOS上个常量,表示操作系统类型
  • Abs()用来返回一个整形数字的绝对值
  • isGreater()用来比较俩个整形数字的大小
  • if 可以包含一个初始化语句(如:给一个变量赋值)(在初始化语句后方必须加上分号)
if val := 10; val<max{
// do something
}

多返回值函数的错误
在函数编程中,经常会使用多返回值的型式,多个一个错误类型error的返回,表示出现的错误。
如果没有出现错误,则error返回为nil,否则返回错误信息

switch结构
  • go的switch可以接收任意形式的表达式,但case必须是相同类型
  • case 可以同时测试多个可能符合的表达式 例如 case val1, val2, val3:
  • defalut分支可以放在任意位置,但最好放在末尾

switch可以不提供任何被判断的值,然后在每个case分支中进行测试不同的条件

例如:

switch {
    case i < 0:
        f1()
    case j == 0:
        f2()
    case k > 0:
        f3()
}

switch 语句还可以包含一个初始化语句

switch result := calculate(); {
    case result < 0:
        ...
    case result > 0:
        ...
    default:
        // 0
}

swtich语句还可以用于type-switch来判断某个interface变量中实际存储的变量类型

for语句

for语句只含判断条件

func main() {
    var i int = 5

    for i >= 0 {
        i = i - 1
        fmt.Printf("The variable i is now: %d\n", i)
    }

也可以把判断条件也去掉,这样会变成一个死循环

for-range结构
  • for-range结构可以迭代任何一个集合
  • for ix,val := range col {}
  • val始终是集合对应索引的值拷贝,因此他只是只读模式,即使修改了val的值,集合中的原值也不会被修改(如果val为指针,则会产生指针的拷贝,依旧可以修改集合中的原值

函数

  • 在go语言中,函数重载是不被允许的
  • Go默认使用按值传递参数,如果想要按引用传递 可以在变量名前面添加 & 符号
  • <其实引用传递也是按值传递。因为指针本身也是数据类型,内容本身就是指向的地址>
  • 在函数调用时,像切片(slice),字典(map),接口(interface),通道(channel)这样的引用类型都是默认使用引用传递(即使没有显式的指出指针)

命名返回值和非命名返回值的区别:

  1. 命名返回值作为结果形参被初始化为相应类型的零值
  2. 命名返回值,返回时只需要一条简单的不带参数的return语句
  3. 即使使用命名返回值,也可以无视他明确返回
func getX2AndX3(input int) (int, int) {
    return 2 * input, 3 * input
}

func getX2AndX3_2(input int) (x2 int, x3 int) {
    x2 = 2 * input
    x3 = 3 * input
    // return x2, x3
    return
}
改变外部变量

传递指针给函数不但可以节省内存,而且赋予了函数直接修改外部变量的能力

package main

import (
    "fmt"
)
// this function changes reply:
func Multiply(a, b int, reply *int) {
    *reply = a * b
}

func main() {
    n := 0
    reply := &n
    Multiply(10, 5, reply)
    fmt.Println("Multiply:", *reply) // Multiply: 50
}
传递变长参数
  • 如果函数的最后一个参数是采用 ...type的形式,那么这个函数就可以处理一个变长的参数。<这个长度可以是0>(可以理解为存储在一个type类型的数组中)
  • func myFunc(a,b,c ...int){} 这个函数可以接收任意个数的int类型的参数
  • 如果参数被存储在一个slice类型的变量s中,则可以通过a… 的形式来传递参数调用变参函数

如果想要达到不同类型的长参数 应该如果传递

  1. 使用结构
    type Options struct {
    par1 type1,
    par2 type2,

    }
  2. 使用空接口
    如果一个变长参数的类型没有被指定,可以使用默认的空接口interface{},可以接收任何类型的参数
    这方案不仅可以用来长度未知的参数,还可以用于任何不确定类型的参数
    func typecheck(…,…,values … interface{}) {
    for _, value := range values {
    switch v := value.(type) {
    case int: …
    case float: …
    case string: …
    case bool: …
    default: …
    }
    }
    }
对空接口的理解
  • 接口:它是一组方法,但它也是一种类型
  • interface{}类型是没有方法的接口
  • 所有类型都满足空接口
    go中接口是由俩个指针组成的
  1. 指向类型相关信息的指针
  2. 指向数据相关信息的指针
defer关键字
  • defer关键字类似于java中的finally语句块,他可以在函数返回前(执行return之后)执行某个语句
  • 一般用于释放某些已分配的资源
package main
import "fmt"

func main() {
    function1()
}

func function1() {
    fmt.Printf("1")
    defer function2()
    fmt.Printf("2")
}

func function2() {
    fmt.Printf("3")
}
//输出结果是 132

特殊情况,这是fmt.print()的坑,在i++后面打印出来是1

func a() {
    i := 0
    defer fmt.Println(i)
    i++
    return
}
// 这里打印出来的 i是 0

当有多个defer行为被注册时,它们会以逆序执行(类似栈,即后进先出)

内置函数
名称说明
close用于管道通信
len、cap len用于返回某个类型的长度或数量(字符串、数组、切片、map 和管道);cap 是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)
new、makenew 和 make 均是用于分配内存:new 用于值类型和用户定义的类型,如自定义结构,make 用于内置引用类型(切片、map 和管道)。它们的用法就像是函数,但是将类型作为参数:new (type)、make (type)。new (T) 分配类型 T 的零值并返回其地址,也就是指向类型 T 的指针。它也可以被用于基本类型:v := new(int)。make (T) 返回类型 T 的初始化之后的值,因此它比 new 进行更多的工作(详见第 7.2.3/4 节、第 8.1.1 节和第 14.2.1 节)new () 是一个函数,不要忘记它的括号
copy、append用于复制和连接切片
panic、recover两者均用于错误处理机制
print、println底层打印函数(详见第 4.2 节),在部署环境中建议使用 fmt 包
complex、real、imag用于创建和操作复数(详见第 4.5.2.2 节)
闭包
  • 闭包函数保存并积累其中的变量的值,不管外部函数退出与否,它都能够继续操作外部函数中的局部变量
  • 在必包中使用的变量,可以在必包函数体内声明,也可以在外部函数声明
package main

import "fmt"

func main() {
//  可以理解为f是指向 函数栈的指针,f没有销毁,则栈不会销毁,所以局部变量一直叠加。
    var f = Adder()
    fmt.Print(f(1), " - ")
    fmt.Print(f(20), " - ")
    fmt.Print(f(300))
}

func Adder() func(int) int {
    var x int
    return func(delta int) int {
        x += delta
        return x
    }
}

结果:

1 - 21 - 321
计算函数执行时间
start := time.Now()
longCalculation()
end := time.Now()
delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值