golang学习笔记(20200302)

自古美人都是妖i 提交于 2020-03-02 12:49:29

//程序入口包
package main

//导包方式一
import "fmt"

//导报方式二
import (
    "fmt"
)

//go设置的GOPATH即为项目的工作路径,改路径下src目录是固定的结构
//导入自定义包的全路劲:%GOPATH%/src/项目名/包名
//eg:包的全路径:%GOPATH%/src/test4go/demo4go
//导包时编译器会默认从%GOPATH%/src路径开始
import (
    "fmt"
    "test4go/demo4go"
)

//当包路径过长,可以给包设置别名,相应的调用函数或变量则需变成以 别名.函数/别名.变量
import(
    alis "test4go/demo4go"
)

//package 后定义的包名可以与包所在目录不同名,但建议保持同名;同一个目录下只能存在一个包名
//go中函数和变量的首字母大小写用以区分是否可跨包访问,大写类似public,小写类似private
//同包中不可以存在同名(区分大小写)的函数或全局变量

函数:

基本语法:

package main

import (
    "fmt"
)

//函数的定义 函数名(参数列表)(返回参数列表)
//无返回值
func print(s string) {
    fmt.Println(s)
}

//单个放回值可以省略返回参数列表的()
func add(i int, j int) int {
    return i + j
}

//多个返回值 返回值顺序与列表一一对应
func sumAndSub(i int, j int)(int, int) {
    sum := i + j
    sub := i - j
    return i, j
}

//多个返回值时 返会列表可以定义返回变量名,方法中的返回按照定义的变量接收即可
func sumAndSub(i int, j int)(sum int, sub int) {
    sum = i + j
    sub = i - j
    return
}

//golang 支持可变参数
func variable(args... int) int {
    var res int = 0
    for i := 0; i < len(args); i ++ {
        res += args[i]
    }
    return res
}

golang函数特性:

函数变量

package main

import (
    "fmt"
)

//main函数为程序的入口
func main () {

    //go中可以将函数赋值给变量
    hi := sayHi
    // hi 的类型为 func (string)

    //函数的指针
    p := &hi
    fmt.Printf("hi 类型 %T,hi 对应的指针(地址) %v,指针 p 类型 %T,p 的指针(地址) %v \n",             
          hi,p, p, &p)

    //函数变量类似于给函数设置别名,调用函数即变为 变量函数()
    hi("lili")

    //无法用指针来调用函数
    // *p("lili") //编译不通过
    //函数变量可以重复赋值同类型的函数
    //hi = sayHello
    //通过指针也可重新赋值同类型函数
    *p = sayHello
    hi("tom")


}

func sayHi(name string) {
    fmt.Println("hi,", name)
}


func sayHello(name string) {
    fmt.Println("hello,", name)
}

匿名函数

pacakge main

import "fmt"

//编译不通过
//通过 := 方式定义变量只能是在方法体内,
//i := 10 该方式等价于两行代码 var i int 和 i = 10,即先申明变量,在给变量赋值
//是顺序执行的代码,故而定义在方法体外会报错

//global := func (str string) {
//    fmt.Println("global + ", str)
//}
var global = func (str string) {
    fmt.Println("global ", str)
}

func main() {
    //匿名函数 
    //函数内定义函数 访问范围为函数体内
    anonymous := func (i int, j int) int {
        return i + j
    }
    sum := anonymous(1, 2)
    fmt.Printf("anonymous type %T, sum = %v", anonymous, sum)

    //也可定义为只执行一次
    //sub为匿名函数执行的结果
    sub := func (i int, j int) int {
        return i - j
    } (2, 3)
    test4Global()
    global("main")
}

func test4Global() {
    global("test")
}

init 函数

//util包
package util
import "fmt"
var utilGlobal = newGlobal4Util()
func init() {
    fmt.Println("util init ---")
}
func newGlobal4Util() string{
    fmt.Println("newGlobal4Util")
    return "util--new--global"
}


//main包
package main
import (
    "fmt"
    "go_code/test4go/demo4init/uitl"
)

var mainGlobal = newGlobal4Main()

func init() {
    fmt.Println("main init ***")
}

func mian() {
    //init为每个包中go文件的函数可用于处理一些初始化的工作
    //需要注意的是 全局变量 init函数 mian的执行顺序
    //导入包的全局变量初始化 》导入包的init函数 》main包中的init 》 main函数执行
    fmt.Println("main ********")
}

func newGlobal4Main() {
    fmt.Println("main**new**global")
}

defer

package main

import "fmt"

//defer 是延迟执行
//defer 后的语句会被压入栈中,该栈即为defer栈,函数执行完成后从defer栈中取出并执行(先进后出)
//defer中的语句所用到的变量均为值拷贝,随语句一同压入defer栈

func main() {
    add(1, 1)
    
}

func add(i int, j int) int {
    defer fmt.Println("add i = ", i)
    defer fmt.Println("add j = ", j)
    i ++
    j ++
    fmt.Println("i = ", i, "j = ", j)
    return i + j
}

自定类型与闭包

package main

import "fmt"

func main() {
    //自定义数据类型
    type myInt int
    var i myInt
    var j int = 10
    //i = j //类型转换
    i = 10
    fmt.Printf("i type: %T val: %v, j type: %T val: %v", i, i, j, j)   
    
    //函数作为参数
    k := afunc(sum, 1, 2)     
    fmt.Println("afunc ----- k = ", k)

    //
    k = bfunc(sum, 2, 1)
    fmt.Println("bfunc --sum--- k = ", k)

    //函数参数列表,返回列表相同,即可认为是同一函数类型
    sub := func (m int, n int) int {
        return m - n
    }
    k = bfunc(sub, 2, 1)
    fmt.Println("bfunc --sub--- k = ", k)
}

func sum(i int, j int) int {
    return i + j
}

//函数参数可接受 函数
func afunc(sumFunc func (int, int) int, i int, j int) int {
    return sumFunc(i, j)
}

//自定义类型
type myFnc func(int, int) int

//将函数定义为自定义类型,可以简化函数的参数列表
func bfunc(sb myFnc, i int, j int) int {
    return sb(i, j)
}

package main

import "fmt"

//闭包可简单理解为函数的返回值为函数
//也可以类比为java中的对象,如下例中,
//closure可理解为一个类,而j可理解为全局变量,addOne和addTwo则可以理解为对应实例的方法
//addOne对应实例全局变量j的初始化值是9,而addTwo的实例全局变量j的初始化值是5
func main() {
	addOne := closure(9)
	fmt.Println("addOne(2) ------- ", addOne(2))
	fmt.Println("addOne(2) ------- ", addOne(2))
	addTwo := closure(5)
	fmt.Println("addTwo(2) ------- ", addTwo(2))
	fmt.Println("addTwo(2) ------- ", addTwo(2))
}

func closure(j int) func(i int) int {
	fmt.Println("j = ", j)
    return func(i int) int{
                j += i
                return j
            }
}

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!