0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Go语言中的函数、方法与接口详解

马哥Linux运维 来源:cnblogs 2024-04-23 16:21 次阅读

函数 (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()

}

上面的程序输出结果是:

2

1 1

1 1

0 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 1

2 2

2 2

3 3

3 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)

}

上面的程序输出结果是:

hello

hello true

0 false

panic: interface conversion: interface {} is string, not float64

。..。..

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 字符串
    +关注

    关注

    1

    文章

    575

    浏览量

    20471
  • 函数
    +关注

    关注

    3

    文章

    4290

    浏览量

    62342
  • 变量
    +关注

    关注

    0

    文章

    613

    浏览量

    28313
  • go语言
    +关注

    关注

    1

    文章

    158

    浏览量

    9016

原文标题:Go 的函数,方法和接口

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Go语言中的整数类型

    Go 语言中,整型可以细分成两个种类十个类型。
    发表于 07-20 15:25 870次阅读

    C语言中指针函数函数指针的概念及应用示例

    在C语言中,指针函数函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据,进而扩展程序的功能。
    发表于 08-16 16:14 700次阅读

    C语言中函数的基本知识

    函数是C语言中的基本构建块之一,它允许我们将代码组织成可重用、模块化的单元。
    发表于 08-16 18:25 503次阅读

    如何使用单击右键选中函数go to definition来查看定义在汇编文件下的函数

    如图所示,函数OSStartHighRdy();是定义在汇编文件下的一个函数,怎样可以像C语言中函数一样,单击右键选中 go to def
    发表于 08-22 01:01

    C语言中atoi()函数应该怎么用?

    C语言中atoi()函数应该怎么用?
    发表于 10-14 09:10

    C语言和汇编语言混合编程方法和C语言中断处理方法

    C语言和汇编语言混合编程方法和C语言中断处理方法,new
    发表于 01-06 14:36 36次下载

    单片机C语言中如何使用nop函数进行短延时的效果资料和程序说明

    单片机C语言中如何使用nop函数进行短延时的效果资料和程序说明 标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。这在汇编
    发表于 03-05 11:01 10次下载
    单片机C<b class='flag-5'>语言中</b>如何使用nop<b class='flag-5'>函数</b>进行短延时的效果资料和程序说明

    详解GO语言的趋势与使用情况

    Go 语言简单易学、性能优良。JetBrains Blog 发布了Go 语言的调查报告,看看GO 语言
    的头像 发表于 03-17 11:05 3016次阅读

    go语言枚举类型怎么用

    go 语言枚举类型是这么用的?在什么场景下会用到枚举?本文对 go 语言枚举做了详细讲解。 枚举,是一种重要的数据类型,由一组键值对组成,通常用来在编程
    的头像 发表于 09-02 09:43 5136次阅读

    详细介绍go语言中的闭包的实现

    什么是闭包? 什么场景下会用闭包 ? 本文对 go 语言中的闭包做了详细介绍。 闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。
    的头像 发表于 10-20 16:18 1829次阅读

    带你了解go语言中的闭包

      【 导读】什么是闭包? 什么场景下会用闭包 ? 本文对 go 语言中的闭包做了详细介绍。 闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。
    的头像 发表于 11-02 15:27 2397次阅读

    C语言怎么跳出while函数

    在C语言中while函数是经常用到的,这里说一下可以跳出while函数的几种方法
    的头像 发表于 06-17 15:40 3.7w次阅读
    C<b class='flag-5'>语言</b>怎么跳出while<b class='flag-5'>函数</b>

    C语言中函数的创建以及使用

    下面我们来介绍一下 C 语言中一个非常重要的概念 - 函数 (function)。首先就要先给函数下一个定义,函数就是完成特定任务的独立代码单元,这也就是说,一个
    的头像 发表于 07-06 09:38 5637次阅读

    go语言中怎么使用HTTP代理

    go语言中怎么使用HTTP代理。
    的头像 发表于 09-01 14:41 2382次阅读

    嵌入式Linux应用开发之go方法与类成员函数

    Go语言中接口就是方法签名(Method Signature)的集合。当一个类型实现了接口中的所有
    发表于 05-13 09:53 347次阅读