go函数使用

Golang 函数定义及使用 Golang 函数定义及基础使用 阅读详情

介绍

每一个程序都包含很多的函数:函数是基本的代码块。
Go是编译型语言,所以函数编写的顺序是无关紧要的;鉴于可读性的需求,最好把 main() 函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(例如函数被调用的顺序)。

Go 里面拥三种类型的函数:

  • 普通的带有名字的函数
  • 匿名函数或者lambda函数
  • 方法
    所有类型的函数都可以有参数与返回值。函数参数、返回值以及它们的类型被统称为函数签名。
    注意
    go语言方法后面要紧跟大括号
    这样是不正确的 Go 代码:
func g()
{
}

它必须是这样的:

func g() {
}

函数被调用的基本格式如下:

pack1.Function(arg1, arg2, …, argn)

Function 是 pack1 包里面的一个函数,括号里的是被调用函数的实参(argument):这些值被传递给被调用函数的形参(parameter)。
一个简单的函数调用其他函数的例子:

package main
func main() {
println("In main before calling greeting")
greeting()
println("In main after calling greeting")
}
func greeting() {
println("In greeting: Hi!!!!!")
}

代码输出:
In main before calling greeting
In greeting: Hi!!!
In main after calling greeting

注意
函数可以将其他函数调用作为它的参数,只要这个被调用函数的返回值个数、返回值类型和返回值的顺序与调用函数所需求的实参是一致的,例如:
假设 f1 需要 3 个参数 f1(a, b, c int) ,同时 f2 返回 3 个参数 f2(a, b int) (int, int, int) ,就可以这样调用 f1: f1(f2(a, b)) 。

注意在 Go 里面函数重载是不被允许的。这将导致一个编译错误:funcName redeclared in this book, previous declaration at lineno

Go 语言不支持这项特性的主要原因是函数重载需要进行多余的类型匹配影响性能;没有重载意味着只是一个简单的函数调度。所以你需要给不同的函数使用不同的名字,我们通常会根据函数的特征对函数进行命名。如果需要申明一个在外部定义的函数,你只需要给出函数名与函数签名,不需要给出函数体:

func flushICache(begin, end uintptr) // implemented externally

函数也可以以申明的方式被使用,作为一个函数类型,就像:type binOp func(int, int) int在这里,不需要函数体 {} 。

函数参数与返回值

  • 按值传递(call by value) 按引用传递(call by reference)
  • 命名的返回值(named return variables)
  • 空白符(blank identifier)
  • 改变外部变量(outside variable)

函数能够接收参数供自己使用,也可以返回零个或多个值(我们通常把返回多个值称为返回一组值)。多值返回是 Go 的一大特性,为我们判断一个函数是否正常执行提供了方便。
我们通过 return 关键字返回一组值。事实上,任何一个有返回值(单个或多个)的函数都必须以return 或 panic 结尾。
在函数块里面, return 之后的语句都不会执行。如果一个函数需要返回值,那么这个函数里面的每一个代码分支(code-path)都要有 return 语句。

按值传递 按引用传递

Go 默认使用按值传递来传递参数,也就是传递参数的副本。函数接收参数副本之后,在使用变量的过程中可能对副本的值进行更改,但不会影响到原来的变量,比如 Function(arg1) 。
如果你希望函数可以直接修改参数的值,而不是对参数的副本进行操作,你需要将参数的地址(变量名前面添加&符号,比如 &variable)传递给函数,这就是按引用传递,比如 Function(&arg1) ,此时传递给函数的是一个指针。如果传递给函数的是一个指针,指针的值(一个地址)会被复制,但指针的值所指向的地址上的值不会被复制;我们可以通过这个指针的值来修改这个值所指向的地址上的值。
几乎在任何情况下,传递指针(一个32位或者64位的值)的消耗都比传递副本来得少。
在函数调用时,像切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型都是默认使用引用传递(即使没有显示的指出指针)。


package main
import "fmt"
func main() {
fmt.Printf("Multiply 2 * 5 * 6 = %d\n", MultiPly3Nums(2, 5, 6))
// var i1 int = MultiPly3Nums(2, 5, 6)
// fmt.Printf("MultiPly 2 * 5 * 6 = %d\n", i1)
}
func MultiPly3Nums(a int, b int, c int) int {
// var product int = a * b * c
// return product
return a * b * c
}

输出显示:
Multiply 2 * 5 * 6 = 60
如果一个函数需要返回四到五个值,我们可以传递一个切片给函数(如果返回值具有相同类型)或者是传递一个结构体(如果返回值具有不同的类型)。因为传递一个指针允许直接修改变量的值,消耗也更少。

命名的返回值(named return variables)

函数带有一个 int 参数,返回两个 int 值;其中一个函数的返回值在函数调用时就已经被赋予了一个初始零值。getX2AndX3 与 getX2AndX3_2 两个函数演示了如何使用非命名返回值与命名返回值的特性。当需要返回多个非命名返回值时,需要使用 () 把它们括起来,比如 (int, int) 。命名返回值作为结果形参(result parameters)被初始化为相应类型的零值,当需要返回的时候,我们只需要一条简单的不带参数的return语句。需要注意的是,即使只有一个命名返回值,也需要使用 () 括起来。

package main
import "fmt"
var num int = 10
var numx2, numx3 int
func main() {
numx2, numx3 = getX2AndX3(num)
PrintValues()
numx2, numx3 = getX2AndX3_2(num)
PrintValues()
}
func PrintValues() {
fmt.Printf("num = %d, 2x num = %d, 3x num = %d\n", num, numx2, numx3)
}
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
}

输出结果:
num = 10, 2x num = 20, 3x num = 30
num = 10, 2x num = 20, 3x num = 30
警告:
return 或 return var 都是可以的。
不过 return var = expression (表达式) 会引发一个编译错误:
syntax error: unexpected =, expecting semicolon or newline or } 。

空白符(blank identifier)

空白符用来匹配一些不需要的值,然后丢弃掉,下面的 blank_identifier.go 就是很好的例子。ThreeValues 是拥有三个返回值的不需要任何参数的函数,在下面的例子中,我们将第一个与第三个返回值赋给了 i1 与 f1 。第二个返回值赋给了空白符 _ ,然后自动丢弃掉。

package main
import "fmt"
func main() {
var i1 int
var f1 float32
i1, _, f1 = ThreeValues()
fmt.Printf("The int: %d, the float: %f \n", i1, f1)
}
func ThreeValues() (int, int, float32) {
return 5, 6, 7.5
}

输出结果:
The int: 5, the float: 7.500000

改变外部变量

传递指针给函数不但可以节省内存,而且赋予了函数直接修改外部变量的能力,所以被修改的变量不再需要使用 return 返回。如下的例子, reply 是一个指向 int 变量的指针,通过这个指针,我们在函数内修改了这个 int 变量的数值。

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,这样的函数称为变参函数。

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

示例函数和调用:

func Greeting(prefix string, who ...string)
Greeting("hello:", "Joe", "Anna", "Eileen")

在 Greeting 函数中,变量 who 的值为 []string{“Joe”, “Anna”, “Eileen”} 。
如果参数被存储在一个数组 arr 中,则可以通过 arr… 的形式来传递参数调用变参函数。

package main
import "fmt"
func main() {
x := Min(1, 3, 2, 0)
fmt.Printf("The minimum is: %d\n", x)
arr := []int{7,9,3,5,1}
x = Min(arr...)
fmt.Printf("The minimum in the array arr is: %d", x)
}
func Min(a ...int) int {
if len(a)==0 {
return 0
}
min := a[0]
for _, v := range a {
if v < min {
min = v
}
}
return min
}

输出:
The minimum is: 0
The minimum in the array arr is: 1

  1. 使用结构:
    定义一个结构类型,假设它叫 Options ,用以存储所有可能的参数:
    type Options struct {
    par1 type1,
    par2 type2,
    …
    }
    函数 F1 可以使用正常的参数 a 和 b,以及一个没有任何初始化的 Options 结构:
    F1(a, b, Options {}) 。如果需要对选项进行初始化,则可以使用F1(a, b, Options {par1:val1, par2:val2}) 。
  2. 使用空接口:
    如果一个变长参数的类型没有被指定,则可以使用默认的空接口 interface{} ,这样就可以接受任何类型的参数。该方案不仅可以用于长度未知的参数,还可以用于任何不确定类型的参数。一般而言我们会使用一个 for-range 循环以及 switch 结构对每个参数的类型进行判断:
func typecheck(..,..,values … interface{}) {
for _, value := range values {
switch v := value.(type) {
case int: …
case float: …
case string: …
case bool: …
default: …
}
}
}

defer 和追踪

关键字 defer 允许我们推迟到函数返回之前(或任意位置执行 return 语句之后)一刻才执行某个语句或函数
关键字 defer 的用法类似于面向对象编程语言 Java 和 C# 的 finally 语句块,它一般用于释放某些已分配的资源。

package main
import "fmt"
func main() {
Function1()
}
func Function1() {
fmt.Printf("In Function1 at the top\n")
defer Function2()
fmt.Printf("In Function1 at the bottom!\n")
}
func Function2() {
fmt.Printf("Function2: Deferred until the end of the calling function!")
}

输出:
In Function1 at the top
In Function1 at the bottom!
Function2: Deferred until the end of the calling function!

请将 defer 关键字去掉并对比输出结果。
使用 defer 的语句同样可以接受参数,下面这个例子就会在执行 defer 语句时打印 0 :

func a() {
i := 0
defer fmt.Println(i)
i++
return
}

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

func f() {
for i := 0; i < 5; i++ {
defer fmt.Printf(“%d “, i)
}
}

上面的代码将会输出: 4 3 2 1 0 。
关键字 defer 允许我们进行一些函数执行完成后的收尾工作,例如:

  1. 关闭文件流:
    // open a file defer file.Close()
  2. 解锁一个加锁的资源
    mu.Lock() defer mu.Unlock()
  3. 打印最终报告
    printHeader() defer printFooter()
  4. 关闭数据库链接
    // open a database connection defer disconnectFromDB()
    合理使用 defer 语句能够使得代码更加简洁。
    以下代码模拟了上面描述的第 4 种情况:
package main
import "fmt"
func main() {
doDBOperations()
}
func connectToDB() {
fmt.Println("ok, connected to db")
}
func disconnectFromDB() {
fmt.Println("ok, disconnected from db")
}
func doDBOperations() {
connectToDB()
fmt.Println("Defering the database disconnect.")
defer disconnectFromDB() //function called here with defer
fmt.Println("Doing some DB operations ...")
fmt.Println("Oops! some crash or network error ...")
fmt.Println("Returning from function here!")
return //terminate the program
// deferred function executed here just before actually returning, even if
// there is a return or abnormal termination before
}

输出:

ok, connected to db
Defering the database disconnect.
Doing some DB operations …
Oops! some crash or network error …
Returning from function here!
ok, disconnected from db
使用 defer 语句实现代码追踪一个基础但十分实用的实现代码执行追踪的方案就是在进入和离开某个函数打印相关的消息,即可以提炼为下面两个函数:

func trace(s string) { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) }

以下代码展示了何时调用两个函数:

package main
import "fmt"
func trace(s string) { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) }
func a() {
trace("a")
defer untrace("a")
fmt.Println("in a")
}
func b() {
trace("b")
defer untrace("b")
fmt.Println("in b")
a()
}
func main() {
b()
}

输出:
entering: b
in b
entering: a
win a
leaving: a
leaving: b

6.5 内置函数
Go 语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型进行操作,
例如:len、cap 和 append,或必须用于系统级的操作,例如:panic。因此,它们需要直接获得编译器
的支持。
以下是一个简单的列表,我们会在后面的章节中对它们进行逐个深入的讲解。
名称 说明
close 用于管道通信
len、cap
len 用于返回某个类型的长度或数量(字符串、数组、切片、map 和管道);cap 是容
量的意思,用于返回某个类型的最大容量(只能用于切片和 map)
new、
make
new 和 make 均是用于分配内存:new 用于值类型和用户定义的类型,如自定义结
构,make 用户内置引用类型(切片、map 和管道)。它们的用法就像是函数,但是
将类型作为参数:new(type)、make(type)。new(T) 分配类型 T 的零值并返回其地
址,也就是指向类型 T 的指针(详见第 10.1 节)。它也可以被用于基本类型:
v := new(int) 。make(T) 返回类型 T 的初始化之后的值,因此它比 new 进行更多的
工作(详见第 7.2.3/4 节、第 8.1.1 节和第 14.2.1 节)new() 是一个函数,不要忘记它
的括号
Go入门指南
本文档使用 看云 构建 - 118 -
copy、
append
用于复制和连接切片
panic、
recover
两者均用于错误处理机制
print、
println
底层打印函数(详见第 4.2 节),在部署环境中建议使用 fmt 包
complex、
real imag
用于创建和操作复数(详见第 4.5.2.2 节)
名称 说明

递归函数

当一个函数在其函数体内调用自身,则称之为递归。最经典的例子便是计算斐波那契数列,即每个数均为前两个数之和。
数列如下所示:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, …
下面的程序可用于生成该数列(示例 6.13 fibonacci.go):

package main
import "fmt"
func main() {
result := 0
for i := 0; i <= 10; i++ {
result = fibonacci(i)
fmt.Printf("fibonacci(%d) is: %d\n", i, result)
}
}
func fibonacci(n int) (res int) {
if n <= 1 {
res = 1
} else {
res = fibonacci(n-1) + fibonacci(n-2)
}
return
}

输出:
fibonacci(0) is: 1
fibonacci(1) is: 1
fibonacci(2) is: 2
fibonacci(3) is: 3
fibonacci(4) is: 5
fibonacci(5) is: 8
fibonacci(6) is: 13
fibonacci(7) is: 21
fibonacci(8) is: 34
fibonacci(9) is: 55
fibonacci(10) is: 89

在使用递归函数时经常会遇到的一个重要问题就是栈溢出:一般出现在大量的递归调用导致的程序栈内存分配耗尽。这个问题可以通过一个名为懒惰求值的技术解决,在 Go 语言中,我们可以使用管道(channel)和 goroutine来实现。

Go 语言中也可以使用相互调用的递归函数:多个函数之间相互调用形成闭环。因为 Go 语言编译器的特殊性,这些函数的声明顺序可以是任意的

将函数作为参数

函数可以作为其它函数的参数进行传递,然后在其它函数内调用执行,一般称之为回调。下面是一个将函数作为参数的简单例子:

package main
import (
"fmt"
)
func main() {
callback(1, Add)
}
func Add(a, b int) {
fmt.Printf("The sum of %d and %d is: %d\n", a, b, a+b)
}
func callback(y int, f func(int, int)) {
f(y, 2) // this becomes Add(1, 2)
}

输出:
The sum of 1 and 2 is: 3

闭包

当我们不希望给函数起名字的时候,可以使用匿名函数,例如: func(x, y int) int { return x + y } 。这样的一个函数不能够独立存在(编译器会返回错误:non-declaration statement outside function body ),但可以被赋值于某个变量,即保存函数的地址
到变量中: fplus := func(x, y int) int { return x + y } ,然后通过变量名对函数进行调用: fplus(3,4) 。当然,您也可以直接对匿名函数进行调用: func(x, y int) int { return x + y } (3, 4) 。下面是一个计算从 1 到 1 百万整数的总和的匿名函数:

func() {
sum = 0.0
for i := 1; i <= 1e6; i++ {
sum += i
}
}()

表示参数列表的第一对括号必须紧挨着关键字 func ,因为匿名函数没有名称。花括号 {} 涵盖着函数体,最后的一对括号表示对该匿名函数的调用。
下面的例子展示了如何将匿名函数赋值给变量并对其进行调用:

package main
import "fmt"
func main() {
f()
}
func f() {
for i := 0; i < 4; i++ {
g := func(i int) { fmt.Printf("%d ", i) }
g(i)
fmt.Printf(" - g is of type %T and has value %v\n", g, g)
}
}

输出:
0 - g is of type func(int) and has value 0x681a80
1 - g is of type func(int) and has value 0x681b00
2 - g is of type func(int) and has value 0x681ac0
3 - g is of type func(int) and has value 0x681400

应用闭包:将函数作为返回值

在程序 function_return.go 中我们将会看到函数 Add2 和 Adder 均会返回签名为 func(b int) int 的函数:

func Add2() (func(b int) int)
func Adder(a int) (func(b int) int)

函数 Add2 不接受任何参数,但函数 Adder 接受一个 int 类型的整数作为参数。
我们也可以将 Adder 返回的函数存到变量中(function_return.go)。

package main
import "fmt"
func main() {
// make an Add2 function, give it a name p2, and call it:
p2 := Add2()
fmt.Printf("Call Add2 for 3 gives: %v\n", p2(3))
// make a special Adder function, a gets value 3:
TwoAdder := Adder(2)
fmt.Printf("The result is: %v\n", TwoAdder(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
}
}

输出:
Call Add2 for 3 gives: 5
The result is: 5

计算函数执行时间

有时候,能够知道一个计算执行消耗的时间是非常有意义的,尤其是在对比和基准测试中。最简单的一个办法就是在计算开始之前设置一个起始时候,再由计算结束时的结束时间,最后取出它们的差值,就是这个计算所消耗的时间。想要实现这样的做法,可以使用 time 包中的 Now() 和 Sub 函数:

start := time.Now()
longCalculation()
end := time.Now()
delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta)

通过内存缓存来提升性能

当在进行大量的计算时,提升性能最直接有效的一种方式就是避免重复计算。通过在内存中缓存和重复利用相同计算的结果,称之为内存缓存。

普通写法:4.730270 秒
内存缓存:0.001000 秒
内存缓存的优势显而易见,而且您还可以将它应用到其它类型的计算中,例如使用 map而不是数组或切片(Listing 6.21 - fibonacci_memoization.go):

package main
import (
"fmt"
"time"
)
const LIM = 41
var fibs [LIM]uint64
func main() {
var result uint64 = 0
start := time.Now()
for i := 0; i < LIM; i++ {
result = fibonacci(i)
fmt.Printf("fibonacci(%d) is: %d\n", i, result)
}
end := time.Now()
delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta)
}
func fibonacci(n int) (res uint64) {
// memoization: check if fibonacci(n) is already known in array:
if fibs[n] != 0 {
res = fibs[n]
return
}
if n <= 1 {
res = 1
} else {
res = fibonacci(n-1) + fibonacci(n-2)
}
fibs[n] = res
return
}

内存缓存的技术在使用计算成本相对昂贵的函数时非常有用(不仅限于例子中的递归),譬如大量进行相同参数的运算。这种技术还可以应用于纯函数中,即相同输入必定获得相同输出的函数。

Golang使用函数来实现接口 使用函数来实现接口实现例子结合匿名函数、闭包的实现实践总结 实现例子 假设我们定义一个日志打印的接口ILogger,还有一个工厂方法ILoggerFactory。 结合匿名函数、闭包的实现实践 总结 阅读详情

相关推荐

Golang 匿名函数使用

最近在研究NSQ中间件,在研究这个中间件的过程中,发现了一些自己在平时开发工作中未使用到的Golang特性;决定记录下在这个过程中学习到的一些知识;本篇文章要写的,是关于Golang匿名函数的使用 匿名函数没有函数名只有函数体,他可以作为一种类型被赋值给函数类型的变量,匿名函数也往往以变量方式传递。 Go语言支持随时在代码里定义匿名函数。 匿名函数,由一个不带函数名的函数声明和函数体组成。简而言之,就是匿名函数可以将作为普通变量使用:能在函数中传递或者是赋值给变量。

飞越蓝天的专栏 503

Golang中函数的使用

函数的基础知识以及函数的特点和函数的使用

周小末天天开心的博客 2946

多目标跟踪中使用trackeval评估dancetrack运行结果

trackeval使用

qq_46144849的博客 1783

【Go语言学习】——函数

函数

Kaychenl的博客 276

ZLMediaKit在Windows下启用WebRtc编译(64位)

准备软件 cmake-gui vs2017 已经编译好的windows版本openssl(下载地址) 当然,你完全可以自己按照openssl的官网教程自己编译windows版本的openssl libsrtp编译安装 首先,需要将下载好的openssl解压并添加到环境变量。如下图,将下图路径添加到环境变量 其次,下载libsrtp(下载地址) 下载后解压并新建build文件夹,如下图: 在合适位置新建文件夹放置install后的srtp文件,如"D:\develop20..

byna11sina11的博客 1万+

基于FastLIO2与TEB算法的机器狗自主导航系统实战

本文详细介绍了如何为机器狗构建一套基于FastLIO2与TEB算法的自主导航系统。通过整合FastLIO2激光惯性里程计实现精准定位,并采用TEB局部规划器进行灵活路径规划与动态避障,解决了传统方案在复杂地形下反应慢、易碰撞的问题。文章提供了从环境搭建、算法部署、地图转换到系统调试的完整实战指南,帮助开发者实现机器狗的稳健自主行走。

beer8的博客 324

go函数(详细)

函数也可以没有返回值,这个时候就无需 return 关键字,例如: main() 入口函数、 init() 初始化函数。当函数体内出现了 panic 函数,用于抛出异常,这时如果定义了返回类型, return 关键字就可以选择省略。如果接受多个值时,某个值没有使用,不能放置在那,要不然编译器会报错,需要使用下划线 "_" 替代,表示不使用。返回值类型指定了名称后,在 return 返回时,可以不带值,当然也可以都带上。return 为函数返回的关键字,携带要返回的值,函数内之后的逻辑将不会执行。

Toml_的博客 564

DPO(Direct Preference Optimization)实战全流程指南

《DPO实战全流程指南》摘要 本文提供了端到端的DPO(直接偏好优化)实战方案,包含数据准备、模型训练、评估部署全流程。核心内容包括: 数据构建:推荐UltraFeedback等高质量数据集,提供数据预处理代码 训练配置:基于HuggingFace TRL库的DPO实现,详解beta值等关键参数调优 工业优化:显存节省技巧(LoRA、梯度检查点)、领域自适应方法和在线学习架构 效果评估:量化对比显示DPO可降低86%有害回复率,提升24%用户满意度 常见问题:针对灾难性遗忘、过度安全化等问题给出解决方案 附

技术引领业务创新 1468

Go语言函数

Go语言函数

YIYIYI 1206

Fiddler抓包实战:5分钟搞定微信公众号历史消息接口分析(附完整Python代码)

本文详细介绍了如何使用Fiddler抓包工具逆向分析微信公众号历史消息接口,并提供完整的Python代码实现。从环境准备、动态参数捕获到商业级采集系统架构设计,全面解析了突破官方接口限制的技术方案,帮助开发者高效获取公众号文章数据。

tree8的博客 330

C++大牛的博客

1. C++大牛的博客     Bjarne Stroustrup的博客: Bjarne Stroustrup’s Homepage Bjarne Stroustrup,不认识的可以去面壁了,没有他,就没有我们现在的饭碗。Bjarne Stroustrup是丹麦人,目前任教于TAMU。他的Homepage和他的书籍The C++ Programming Language一样

程序猿老樊的博客 6249

Go 语言的函数详解:语法、用法与最佳实践

在 Go 语言中,函数是基本的代码块,每一个程序都包含很多的函数。Go 函数的功能非常强大,以至于被认为拥有函数式编程语言的多种特性。Go 是编译型语言,所以函数编写的顺序是无关紧要的;鉴于可读性的需求,最好把main()函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(例如函数被调用的顺序)。编写多个函数的主要目的是将一个需要很多行代码的复杂问题分解为一系列简单的任务(那就是函数)来解决。而且,同一个任务(函数)可以被调用多次,有助于代码重用。

栗筝i的博客 3244

Ubuntu搭建Pytorch环境(Anaconda、Cuda、cuDNN、Pytorch、Python、Pycharm、Jupyter)

Ubuntu搭建Pytorch环境(Anconda、Cuda、Pytorch、Python、Pycharm、Jupyter)

funfan的博客 1万+

fp-go:Golang 的函数式编程库使用指南

fp-go:Golang 的函数式编程库使用指南 1. 项目介绍 fp-go 是一个基于 Go 语言 1.18+ 泛型的强大函数式编程助手集合。受到 fp-ts(TypeScript 中的函数式编程库)的启发,这个项目旨在为Go开发者提供一系列实用工具,以便在日常开发中采用函数式编程风格。它包含了诸如 Currying(柯里化)、Filter、FlatMap、Map、Reduce 等核心高阶函数...

gitblog_00123的博客 1076

学Simulink——基于Simulink的超前-滞后校正控制器设计与仿真建模示例

本文完成了基于 Simulink 的超前-滞后校正控制器设计与仿真,实现了:✅掌握超前与滞后校正的物理意义与设计流程✅分步设计复合控制器,兼顾动态与稳态✅在 Simulink 中搭建闭环系统并验证卓越性能✅达成高稳定裕度、高精度、快速响应三大目标。

xiaoheshang_123的博客 81

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

go run 使用其他函数_golang使用webAssembly的方式

WebAssembly (WASM) 是一种新的编码方式,可以在现代的网络浏览器中运行- 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能. 可以将C/C++/Rust/GO代码编译成.wasm文件, 然后运行在web上面.本文仅介绍Golang与WASM使用的相关基础知识.环境需要golang版本高于go1.11, 本文golang版本:$ go version > go...

weixin_36051235的博客 872

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【Go】Golang使用反射实现RPC函数调用

Golang使用反射实现简单的单向RPC函数调用

vosats的博客 803

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

php 使用 go函数指针,golang new 函数的使用

今天看到一道题,先来看看题目type Point struct {X, Y float64}func (p *Point) Abs() float64 {return math.Sqrt(p.X*p.X + p.Y*p.Y)}func main() {var p *Pointfmt.Println(p.Abs())}问这个为什么会 panic?panic: runtime error: inval...

weixin_42387906的博客 121

php go函数,使用 Go 实现 PHP 常用内置函数 php2go

软件介绍php2go —— 使用 Golang 实现 PHP 常用内置函数,目前已经实现了 140+ 函数。下载&安装gogetgithub.com/syyongx/php2goPHP FunctionsDate/Time Functionstime()strtotime()date()checkdate()sleep()usleep()String Functionsstrpos()...

weixin_28304023的博客 794

golang 函数的使用

golang 函数的使用

Lai助网络科技的博客 341

【Golang】4.用代码形式总结go的函数部分的知识及使用

package main import ( "fmt" "math" ) //go语言函数 /* func 函数名 ([参数列表]) [返回值]{ 函数体 } */ //单返回值, 此形式为值传递, 不影响下面a,b实际的值 func getMax(num1, num2 int) int { if(num1 > num2){ return num1 }else{ return num2 } } //返回多个参数返回值, 此形式为值传递 func swap(name1 str

爱放火的安小妮的博客 222

golang - 函数的使用

说明:包的快速入门——》Go 相互调用函数使用包里面的函数。

2401_86984695的博客 850

php 使用 go函数指针,golang 什么时候使用指针

有时候看别人的go代码,发现他们有的在代码里面用了指针,有的不使用。假设有个结构体类型叫做Person,发现有些方法会用func methodA (*person Person)作为参数,或者使用 func *(person Person) methodA()作为结构体自己的方法,也就是person这个结构体 (推荐学习:go)可以直接调用methodA,但...

weixin_39678163的博客 168

[Golang 学习1]Go语言中函数new与make的使用和区别

Go语言中函数new与make的使用和区别 简介 Go语言中有两个生成函数new与make,容易混淆。故总结一下使用和区别。 Go语言中new和make是内建的两个函数,主要用来创建分配类型内存。 问题的引出:变量声明 var i int var s string 变量的声明我们可以通过var关键字,然后就可以在程序中使用。 当我们不指定变量的默认值时,这些变量的默认值是他们的零值,比如:int...

oRewrite的博客 482

GO-使用golang实现C语言中的memset函数效果

void *memset(void *s, int ch, size_t n); 函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。 memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法 。 memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组,c:是赋给buffer的值,c

a_lzq的博客 1281

Golang之函数的使用

Golang作为一种面向对象的语言,函数式编程的思想十分重要。不同语言的特点各有不同,在函数方面我总结了以下几点go支持:可变长参数;函数也可作为一种类型,可以作为参数传递、赋值;支持匿名函数、闭包;支持多个返回值或无返回值;支持命名参数返回不支持:一般情况下,有名函数不支持嵌套,匿名函数可以嵌套;不支持重载(一个包中函数名不能重复);不支持默认参数

fruitless的博客 268
上一篇: go语言控制流
下一篇: jvm 内存区域划分
过去日记
过去日记 新星创作者: 后端开发技术领域 新星创作者: 后端开发技术领域
博客等级 码龄3年 5343粉丝 225原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过去日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值