Livfer's Blog


  • 首页

  • 标签

  • 分类

  • 归档

go匿名函数

发表于 2019-07-11 | 分类于 go

定义

Go中的匿名函数和PHP类似,区别就是在Go中参数以及返回值的类型必须声明

匿名函数同样被称之为闭包(函数式语言的术语):它们被允许调用定义在其它环境下的变量。闭包可使得某个函数捕捉到一些外部状态,例如:函数被创建时的状态。另一种表示方式为:一个闭包继承了函数所声明时的作用域。这种状态(作用域内的变量)都被共享到闭包的环境中,因此这些变量可以在闭包中被操作,直到被销毁

1
2
3
func(a,b int) int {
return a+b
}(1,2) //最后直接带上括号代表直接执行此匿名函数

应用

将匿名函数作为返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {
p2 := Add2()
fmt.Println(p2(3))

add2 := Adder(1)
fmt.Println(add2(3))
}

func Add2() func(b int) int {
return func(b int) int {
return b + 2
}
}

func Adder(a int) func(b int) int {
return func(b int) int {
return a + b
}
}
// 5
// 4

保证局部变量安全性

闭包内部声明的局部变量无法从外部修改,从而确保了安全性(类似类的私有属性):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

var j int = 1


func main() {
f := func() {
var i int = 1
fmt.Printf("i, j: %d, %d\n", i, j)
}
f()
j += 2
f()
}
//i, j: 1, 1
//i, j: 1, 3
// i为匿名函数内部变量,外部无法修改,j为外部变量,可以修改

匿名函数作为参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main() {
i := 10
add := func(a, b int) {
fmt.Println("外部变量i:",i)
fmt.Println("作为参数传递到外部函数,参数a:",a,"参数b:",b,"返回值:",a + b)
}
callback(1,add)
}

func callback(x int ,f func(int,int)) {
f(x,2)
}

//外部变量i: 10
//作为参数传递到外部函数,参数a: 1 参数b: 2 返回值: 3

使用闭包调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"log"
"runtime"
)

func main() {
where := func() {
_, file, line, _ := runtime.Caller(1)
log.Printf("%s:%d", file, line)
}
where()
log.SetFlags(log.Lshortfile)
log.Print("Log包获取文件短信息")
log.SetFlags(log.Llongfile)
log.Print("log包获取文件长信息")
// 2019/07/11 16:42:03 /path/go/calc/src/1.go:13
// 1.go:15: Log包获取文件短信息
/// /path/go/calc/src/1.go:17: log包获取文件长信息
}

go函数变长参数

发表于 2019-07-10 | 分类于 go

变长参数定义

Go函数的变长参数类似于PHP5.6之后的方式

func myFunc(a,b...int){}

变长参数要点:

  • 变长参数必须为最后一个
  • 可以通过for循环获取参数
  • 类型不同的变长参数可以通过结构和空接口来实现
阅读全文 »

go函数参数和返回值

发表于 2019-07-10 | 分类于 go

go中函数参数和PHP中类似,区别是go中的函数参数必须是指定类型的(这是必须的).

go的函数体中如果有return关键字返回,那么此函数必须以return或panic结尾

按值传递和按引用传递

Go中默认是按值传递,和PHP中类似.引用传递也和PHP类似,变量前加上&

比如funA(&arg),此时传递的是一个指针,当传递指针时,这个指针的值(变量指向的地址)会被复制,但指针的值所指向的地址上的值不会被复制.其实本质上,指针传递也是按值传递,只不过此时传递的是指针的值.

传递指针给函数不但可以节省内存(因为没有复制变量的值),而且赋予了函数直接修改外部变量的能力,所以被修改的变量不再需要使用 return 返回

切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型 默认使用引用传参(即使没有显示的指出指针,类似 PHP 中把对象实例作为函数参数

阅读全文 »

go函数基本

发表于 2019-07-09 | 分类于 go

go中函数包括:

  • 普通带名字的函数(和PHP类似)
  • 匿名函数(和PHP类似)和lambda函数
  • 类方法

普通函数定义

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
fmt.Println(add(1,2))
}

func add(a,b int) int {
return a + b
}

PHP区别

  • 参数类型必须声明,如果参数类型一样可以最后声明一次就可以(PHP非严格模式可省略)
  • 返回值类型必须声明(PHP非严格模式可省略)
  • 同一目录下go文件中的方法可以直接调用
  • 不同目录下go文件中的方法必须要引入包
  • 在跨包调用时,只有首字母大写的函数(类似public)才可以被调用,小写字母函数只能在包内调用

break,contine和goto

发表于 2019-07-09 | 分类于 go

break,continue

break,continue与PHP中的类似,通过break跳出当前最内部循环,通过continue执行下一次循环,go中可以通过标签进行跳转标签处

阅读全文 »

go流程控制

发表于 2019-07-09 | 分类于 go

go中的流程控制和PHP类似主要包含以下几种:

  • if,if else,else if
  • switch,case,select
  • for,range
  • goto
阅读全文 »

go数据类型Map

发表于 2019-07-09 | 分类于 go

Map 声明,初始化,和make

go中的map相当于PHP中的关联数组,(key=>value关系集合),不同在于go中的必须指定key和value的数据类型,且是无序的,不会按照插入的顺序排序

阅读全文 »

go数据类型-切片

发表于 2019-06-28 | 分类于 go

概念

切片类似于PHP可操作的所以数据,属于go中可动态改变的特殊数组

切片在go中是一个新的数据类型,与数组最大的不同在于,切片的类型字面量中只有元素的类型,没有长度

切片有三种创建方式: 基于数组,数组切片,直接创建

切片在内存中的组织方式实际上是一个有 3 个域的结构体:指向相关数组的指针,切片 长度以及切片容量。下图给出了一个长度为 2,容量为 4 的切片

var x = []int{2, 3, 5, 7, 11}

y := x[1:3] //右边不包括 3,5

阅读全文 »

go数据类型-数组

发表于 2019-06-28 | 分类于 go

与PHP比较

  • go中数组是固定长度的
  • 元素必须是同一类型的数据集合
  • 声明的时候必须制定元素类型和数组长度

go中的数组可以理解为是PHP中的索引数组

阅读全文 »

go基本数据类型转换

发表于 2019-06-27 | 分类于 go

PHP类型转化

PHP类型转化是自动转化的

1
2
3
4
5
6
7
$a = 1;
$b = 2;
$c = "string";
$d = true;
echo $a+$b; //3
echo $a+$d; //3 true->1
echo $a.$c; //1string $a转为字符串

go类型转化

阅读全文 »
1…456…8
Livfer

Livfer

代码的搬运工

73 日志
18 分类
39 标签
GitHub E-Mail
Links
  • 🍊程成🍊
© 2020 Livfer
由 Hexo 强力驱动
|
主题 — NexT.Mist