Redian新闻
>
Go 的函数,方法和接口

Go 的函数,方法和接口

公众号新闻


函数 (function)

  • 函数可以没有参数或者接受多个参数。

  • 当连续两个或多个函数的已命名形参类型相同时,除最后一个类型以外,其它都可以省略。

func add(x, y int) int {    return x + y}
  • 函数(或者变量)的名称以大写字母开头时,它就是已导出的。

  • 函数可以返回任意数量的字符串。

func swap(x, y string) (string, string) {    return y, x}


  • 函数的返回值可以被命名,它们会被视作在函数顶部定义的变量,没有参数的 return 返回已经被命名的返回值。

func division(dividend, divisor int) (quotient, remainder int) {    quotient = dividend / divisior    remainder = dividend - quotient * divisor    return}


  • 函数也是值,也可以用作函数的参数和返回值。

// conpute 接受一个函数作为参数// 调用 conpute 时传入不同的函数,返回对3和4作不同的操作的结果func conpute(fn func(float64, float64) float64) float64 {  return fn(3, 4)}


函数的闭包 (closure)

  • A closure is a record storing a function together with an environment.

  • 闭包是由函数和环境组合而成的。闭包保存和记录了它产生时的外部环境——它的函数体之外的变量,并且可以访问和修改这些变量。

  • 在闭包实际实现的时候,往往通过调用一个外部函数返回其内部函数来实现的。用户得到一个闭包,也等同于得到了这个内部函数,每次执行这个闭包就等同于执行内部函数。

  • 如果外部函数的变量可见性是 local 的,即生命周期在外部函数结束时也结束的,那么闭包的环境就是封闭的。反之,那么闭包其实不再封闭,全局可见的变量的修改,也会对闭包内的这个变量造成影响。

package main
import "fmt"
func test_1(x int) func() { return func() { x++ fmt.Println(x) }}
func test_2(x int) func() { sum := 0 return func() { sum += x fmt.Println(x, sum) }}
func test_3(x int) func(int) int { sum := 0 return func(y int) int { sum += x * y return sum }}
func main() { test_1(1)()
test_2(1)()
// 每个闭包事实上有着不同的外部环境 // 即:对每个 for 循环,都会新建一个 test_3() // 所以每个闭包绑定的是不同的 sum 变量 for i := 0; i < 5; i++ { fmt.Printf("%d ", test_3(1)(i)) } fmt.Println()
// 每个闭包的外部环境相同(tmp) // 即 for 循环中的闭包绑定的是同一个 sum 变量 tmp := test_3(1) for i := 0; i < 5; i++ { fmt.Printf("%d ", tmp(i)) } fmt.Println()}


上面的程序输出结果是:

21 11 10 1 2 3 4 0 1 3 6 10


方法 (method)

  • Go 没有类,不过可以为结构体类型定义方法。方法就是一类带特殊的接收者参数的函数。方法接收者在它自己的参数列表内,位于 func 关键字和方法名之间。(非结构体类型也可以定义方法)

type Vertex struct {  X, Y float64}
func (v Vertex) distance() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y)}


  • 方法并不能修改指针接收者的值。只有指针接收者的方法能够修改接收者指向的值。(在这种情况下,方法也没有修改接收者的值——指针的内容,只是修改了指针指向的值,和用指针作为参数是一样的)

  • 在很多意义上,方法的接收者和普通的参数是一样的。如果不使用指针。

  • 不过,带指针参数的函数必须接受一个指针,而以指针为接受者的方法被调用时,接受者接收者既能为值又能为指针。

package main
import "fmt"
type Vertex struct { X, Y float64}
func (v *Vertex) Move_1(dx, dy float64) { v.X += dx v.Y += dy}
func (v Vertex) Move_2(dx, dy float64) { v.X += dx v.Y += dy}
func Move_3(v *Vertex, dx, dy float64) { v.X += dx v.Y += dy}
func Move_4(v Vertex, dx, dy float64) { v.X += dx v.Y += dy}
func main() { var v Vertex v.X = 0 v.Y = 0. v.Move_1(1, 1) fmt.Println(v.X, v.Y) p := &v p.Move_1(1, 1) fmt.Println(v.X, v.Y) v.Move_2(1, 1) fmt.Println(v.X, v.Y) Move_3(&v, 1, 1) fmt.Println(v.X, v.Y) Move_4(v, 1, 1) fmt.Println(v.X, v.Y)}


上面的程序输出结果是:

1 12 22 23 33 3

接口 (interface)

  • 接口是一组方法签名的集合,接口类型的变量可以保存任何实现了这些方法的值。

  • Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。没有 implements 关键字。

type MyFloat float64
func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f)}
type Vertex struct { X, Y float64}
func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y)}
type Abser interface { Abs() float64}
func main() { var a Abser f := MyFloat(-math.Sqrt2) v := Vertex{3, 4}
a = f // MyFloat 实现了 Abs() a = &v // *Vertex 实现了 Abs()}


  • 指定了零个方法的接口值被称为空接口,可以保存任何类型的值(因为每个类型都至少实现了零个方法)。空接口被用来处理未知类型的值。

  • 在内部,接口值可以看做包含值和具体类型的元组,类型断言提供了访问接口值底层具体值的方式。

package main
import "fmt"
func main() { var i interface{} = "hello"
// 该语句断言接口值 i 保存了具体类型 string, // 并将其底层类型为 string 的值赋予变量 s。 // 若 i 并未保存 string 类型的值,该语句就会触发 panic。 s := i.(string) fmt.Println(s)
// 为了判断一个接口值是否保存了一个特定的类型, // 类型断言可返回两个值:其底层值以及一个报告断言是否成功的布尔值。 // 若 i 保存了一个 string,那么 s 将会是其底层值,而 ok 为 true。 // 否则,ok 将为 false 而 s 将为 T 类型的零值,程序并不会产生 panic。 s, ok := i.(string) fmt.Println(s, ok)
f, ok := i.(float64) fmt.Println(f, ok)
f = i.(float64) // 报错 (panic) fmt.Println(f)}


上面的程序输出结果是:

hellohello true0 falsepanic: interface conversion: interface {} is string, not float64......


链接:https://www.cnblogs.com/tea-in-the-snow/p/17997981

(版权归原作者所有,侵删)


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
从美加边境偷渡入美,华女和接应司机被捕非法入境美国!华女和接应司机被捕“我们也要有好的兵法和有效的武器!”chatgpt的答案有误?收入连续增长,方舟健客如何跑通互联网慢病管理?【行业日报】 马斯克的Neuralink公司遭遇严重挑战!美国将加大对于人工智能技术的立法和赞助!全球增长平台「汇量科技」:全产品线招人,最缺广告算法和海外营销人才|春季招聘报道【C语言】内联函数总结王一博《追风者》大结局:看懂这6句话,方为人间清醒黄仁勋每天都用的 AI 产品,来自 Google,颠覆 GoogleJellycat限时巨折!2折起:英国优衣库/Diesel/GoldenGoose/We11done等!用完就扔的厨房湿纸巾,清洁到位,方便又好用!GO GO GO !步行非法入境美国!华女和接应司机双双被捕财经早参丨国资委确定首批启航企业;钟南山:当前无需对X疾病过于恐慌;连续两年未分红,方大特钢遭问询教育的最高境界,是让孩子的内心充满能量,方法超简单(值得一看)这就是OpenAI神秘的Q*?斯坦福:语言模型就是Q函数GO接口三个特性普京受中方高规格接待,抵达时间和接机的女官员很不寻常一地鸡毛(2)接受访问学者,促进中美文化与学术交流过了这么多年清明,方知此是中国人的感恩节OCC-WCC 2024特别策划丨历届回顾—— 一日千里,方兴未艾:2015年-2019年一年走掉6万员工!IKEA高层出招成功降低离职率,方法曝光带你拿捏Go空接口法律翻译|牛津法律与经济学手册:私法和商法垦丁,台湾的海角天涯又有一位保险“老将”去职,方力辞任富德生命人寿董事长姐姐没上过几节奥数,两个一等奖和一个大师银,被清华附点招,妹妹死都不学奥数,却被北大附点招,招生老师想法都很清奇|Ellie妈妈师生恋?小张老师说“不”!为什么说席卷美国校园的“挺巴”抗议,无法和当年反越战运动相比?GOLANG接口三个特性美国将向苏丹人民和接收难民的社区追加人道主义援助栽了!从美加边境偷渡入美,华人女子和接应司机被捕!Pylon框架:在PyTorch中实现带约束的损失函数
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。