Go 语言基础(三) 之 函数

内建函数

1、预定义了少数函数,这意味着无需引用任何包就可以使用它们

close 用于 channel 通讯。

delete 用于在 map 中删除实例

len 和 cap 可用于不同的类型, len 用于返回字符串、slice 和数组的长度。

new 用于各种类型的内存分配。

make 用于内建类型(map、slice 和 channel)的内存分配。

copy 用于复制 slice。

append 用于追加 slice。

panic 和 recover 用于异常处理机制。

print 和 println 是底层打印函数,可以在不引入 fmt 包的情况下使用。它们 主要用于调试。

complex、real 和 imag 全部用于处理 复数。

可以利用 array 在列表中进行多个值的排序,或者使用更加灵活的:slice。字典

或哈希类型同样可以使用,在 Go 中叫做 map。

2、array

array 由 [n]<type> 定义, n 标示 array 的长度,而 <type> 标示希望存储的内容的 类型。

对 array 的元素赋值或索引是由方括号完成的:

var arr [10]int

arr[0] = 42

arr[1] = 13

fmt.Printf("The first element is %d\n", arr[0])

像 var arr = [10]int 这样的数组类型有固定的大小。大小是类型的一部分。由于不同的大小是不同的类型,因此不能改变大小。

数组同样是值类型的:将一个数组赋值给另一个数组,会复制所有的元素。

尤其是当向函数内传递一个数组的时候,它会获得一个数组的副本,而不是数组的指针。

可以像这样声明一个数组:var a [3]int,如果不使用零来初始化它,

则用复合声明:a := [3]int{1, 2, 3} 也可以简写为 a := [...]int{1, 2, 3},Go 会自动统计元素的个数。

注意,所有项目必须都指定。因此,如果你使用多维数组,有一些内容你必须录入:

a := [2][2]int{ [2]int{1,2}, [2]int{3,4} } 类似于:

a := [2][2]int{ [...]int{1,2}, [...]int{3,4} }

当声明一个 array 时,你必须在方括号内输入些内容,数字或者三个点 (...)。

3、slice

slice 与 array 接近,但是在新的元素加入的时候可以增加长度。

slice 总是指向底层的一个 array。

slice 是一个指向 array 的指针,这是其与 array 不同的地方;

slice 是引用类型,这意味着当赋值某个 slice 到另外一个变量,两个引用会指向同一个 array。

例如,如果一个函数需要一个 slice 参数,在其内对 slice 元素的修改也会体现在函数调用者中,

这和传递底层的 array 指针类似。通过:

sl := make([]int, 10)

创建了一个保存有 10 个元素的 slice。需要注意的是底层的 array 并无不同。

slice 总是与一个固定长度的 array 成对出现。其影响 slice 的容量和长度。

首先创建了 m 个元素长度的 array,

元素类型 int: var array[m]int

然后对这个 array 创建 slice: slice := array[0:n] 然后现在有:

? len(slice)== n ;

? cap(slice)== m ;

? len(array)== cap(array)== m

4、map

在 Go 中有 map 类型。map 可以认为是一个用字符串做索引的数组(在其最简单的形式下)。

下面定义了 map 类型,用于将 string(月的缩写) 转换为 int – 那个月的天数。

一般定义 map 的方法是:map[<from type>]<to type>

monthdays := map[string]int{

"Jan": 31, "Feb": 28, "Mar": 31,

"Apr": 30, "May": 31, "Jun": 30,

"Jul": 31, "Aug": 31, "Sep": 30,

"Oct": 31, "Nov": 30, "Dec": 31, ← 逗号是必须的

}

留意,当只需要声明一个 map 的时候,使用 make 的形式:

monthdays := make(map[string]int)

当在 map 中索引(搜索)时,使用方括号。

例如打印出 12 月的天数:

fmt. Printf("%d\n", monthdays["Dec"])

当对 array、slice、string 或者 map 循环遍历的时候,

range 会帮助你,每次调用,它都会返回一个键和对应的值。

year := 0

for _, days := range monthdays { ← 键没有使用,因此用 _, days

year += days

}

fmt.Printf("Numbers of days in a year: %d\n", year)

向 map 增加元素,可以这样做:

monthdays["Undecim"] = 30 ← 添加一个月

monthdays["Feb"] = 29 ← 年时重写这个元素

检查元素是否存在,可以使用下面的方式:

var value int

var present bool

value, present = monthdays["Jan"] ← 如果存在,present 则有值 true ← 或者更接近 Go 的方式

v, ok := monthdays["Jan"] ← “逗号 ok”形式

也可以从 map 中移除元素:

delete(monthdays, "Mar") ← 删除"Mar" 吧,总是下雨的月

通常来说语句 delete(m, x) 会删除 map 中由 m[x] 建立的实例。

八、函数

1、函数是构建 Go 程序的基础部件

type mytype int ← 新的类型,参阅第 5 章

func (p mytype) funcname(q int) (r,s int) { return 0,0 }

函数没有返回值:

func subroutine(in int) {

return

}

简单的将输入返回:

func identity(in int) int {

return in

}

递归函数:

func rec(i int) { if i == 10 {

return }

rec(i+1)

fmt.Printf("%d ", i)

}

这会打印:9 8 7 6 5 4 3 2 1 0。

2、作用域

定义在函数外的变量是全局的,那些定义在函数内部的变量,对于 函数来说是局部的。如果命名覆盖——一个局部变量与一个全局变量有相同的 名字——在函数执行的时候,局部变量将覆盖全局变量

package main

var a int

func main() {

a=5

println(a)

f()

}

func f() {

a := 6

println(a)

g()

}

func g() {

println(a)

}

输出内容将是:565。

局部变量仅仅在执行定义它的函数时有效

3、多值返回

函数和方法可以返回多个值

func nextInt(b []byte, i int) (int, int) {

x := 0

// 假设所有的都是数字

for ; i < len(b); i++ {

x = x*10 + int(b[i])-‘0‘

}

return x, i

}

你可以在输入的数组中扫描数字,像这样:

a := []byte{‘1‘, ‘2‘, ‘3‘, ‘4‘}

var x int

for i := 0; i < len(a); { ← 没有 i++

x, i = nextInt(a, i)

println(x)

}

4、命名返回值???

5、延迟代码???

假设有一个函数,打开文件并且对其进行若干读写。在这样的函数中,经常有 提前返回的地方。如果你这样做,就需要关闭正在工作的文件描述符。

defer 语句。

在 defer 后指定的函数会在函数退出前调用。

for i := 0; i < 5; i++ {

defer fmt.Printf("%d ", i)

}

延迟的函数是按照后进先出(LIFO)的顺序执行,所以上面的代码打印: 4 3 2 1 0。

在 defer 中访问返回值

func f() (ret int) { ← ret 初始化为0

defer func() {

ret++ ← ret 增加为1

}()

return 0 ← 返回的是1 而不是0

}

6、变参

接受变参的函数是有着不定数量的参数的

func myfunc(arg ...int) {}

arg ... int 告诉 Go 这个函数接受不定数量的参数

7、函数作为值

函数也是值

匿名函数

func main() {

a := func() { ← 定义一个匿名函数,并且赋值给 a

println("Hello")

} ← 这里没有 ()

a() ← 调用函数

}

如果使用 fmt.Printf("\%T\n", a) 打印 a 的类型,输出结果是 func()。

8、回调

当函数作为值时,就可以很容易的传递到其他函数里,然后可以作为回调。

首先定义一个函数,对整数做一些 “事情”:

func printit(x int) { ← 函数无返回值

fmt.Print("%v\n", x) ← 仅仅打印

}

这个函数的标识是 func printit(int),或者没有函数名的:func(int)。

创建新的函数使用这个作为回调,需要用到这个标识:

func callback(y int, f func(int)) { ← f 将会保存函数

f(y) ← 调用回调函数 f 输入变量 y

}

时间: 2024-10-23 15:22:31

Go 语言基础(三) 之 函数的相关文章

Object Pascal 语法之语言基础(三)

1.6 Object Pascal 的运算符 运算符是程序代码中对各种类型的数据进行计算的符号,通常分为算数运算符.逻辑运算符.比较运算符和按位运算符. 1.算术运算符Object Pascal 语言的算术运算符,如表1-9 所示.表1-9 Object Pascal 语言算术运算符 操作符 操作 操作数据类型 结果类型 + 加 整型.实型 整型.实型 - 减 整型.实型 整型.实型 * 乘 整型.实型 整型.实型 / 除 整型.实型 整型.实型 mod 取余 整型 整型 div 整除 整型 整

go语言基础(main函数、数据类型)

go语言基础(main函数.数据类型) 1.Go语言介绍 Go语言是云计算时代的c语言 c和c++这类语言提供了很快的执行速度,而Rudy和python这类语言则擅长快速开发.Go语言则介于两者之间,不仅提供了高性能的语言,同时也让开发更快速 优势 部署简单,可直接编译成机器码.不依赖其他库,部署就是扔一个文件上去就完成了 静态类型语言(c是静态语言.python解释性语言),但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,

VBA语言(三)函数

一.函数过程 1.VBA有以下三种函数过程: 子程序过程(子程序)执行一些有用的任务但是不返回任何值.他们以关键字Sub开头,和关键字End Sub结束: 函数过程(函数)执行具体的任务并返回值.以关键字Function开头,End Function结束: 属性过程用于自定义对象.使用属性过程,你可以设置和获取对象属性的值,或者设置对另外一个对象的引用. 2.创建函数过程 关于函数名称 函数名称应该点名该函数的作用,并且必须和变量的命名规则一致. 创建函数 1)声明一个空函数过程: Public

小白学习之路,基础三(函数)

一,函数的基本介绍 首先谈到函数,相信大家都不陌生,不管是其他语言都会用到,可能就是叫法不一样.就我知道的跟python中函数类似的,在C中只有function,在Java里面叫做method,在js中也是叫function.函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这被叫做用户自定义函数. 函数有下面三点好处: 1.能够减少重复代码的使用 2

黑马程序员--C语言基础之--scanf函数

------- IOS培训期待与您交流! ---------- 写代码的时候,我们可以看得出,几乎每一个C程序都会包括输入输出.输入输出是程序中最基本的操作之一.C语言本身并不提供输入输出的语句,输入输出操作是由C标准函数库中的函数来实现的.今天就先说说输入:scanf函数. scanf函数与printf函数一样,都不是C语言的关键字,而只是函数库的名字,它们被定义在stdio.h里,因此在使用scanf函数时要加 上#include<stdio.h>.它是格式输入函数,即按用户指定的格式从键

黑马程序员--C语言基础之--printf函数

------- IOS培训期待与您交流! ---------- 上一篇介绍了C语言中scanf函数的用法,接下来让我们来进一步地认识了解一下printf函数. 一.printf函数的用法: 首先让我们来看一下其定义的格式: int printf(const char *format,[argument]) (一).一般格式 printf(格式控制,输出表列); 如: printf("i=%d,ch=%c/n",i,ch); 说明: (1)."格式控制"是用双撇号括起

[java学习笔记]java语言基础概述之函数的定义和使用&amp;函数传值问题

1.函数 1.什么是函数? 定义在类中的具有特定功能的一段独立小程序. 函数也叫做方法 2.函数的格式 修饰符   返回值类型    函数名(参数类型  形式参数1, 参数类型  形式参数2-) {           执行语句(函数体);           return 返回值;       } 返回值类型:函数运行完成后输出的数据类型. 参数类型:是形式参数的数据类型. 形式参数:是一个变量,用于储存调用函数时传递给函数的实际参数. 实际参数:传递给形参的实际数据. return:结束函数

C语言基础知识【函数】

C 函数1.函数是一组一起执行一个任务的语句.每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数.您可以把代码划分到不同的函数中.如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的.函数声明告诉编译器函数的名称.返回类型和参数.函数定义提供了函数的实际主体.C 标准库提供了大量的程序可以调用的内置函数.例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置

C语言基础三

程序执行顺序: 1.顺序结构 2.条件结构;if条件结构,if...else条件结构,多重if条件分支结构(if...elseif..else)和switch条件结构 3.循环结构:do....while循环,while循环,for循环 运算符: 算术运算符(按照操作数分类) 1.一元操作符 ++,-- 2.二元运算符:+,-,*,/,%(取模或求余) 赋值运算符:= 复合赋值运算符:+=,-=,*=,/=.%= 比较运算符:比较数值的大小关系(<,>,<=,>=,!=,==) 逻

C语言基础总结 ( 一 )----------函数和进制的总结

1. 函数分类 1) 无参无返回值函数一般用于执行某些固定的功能.(打印logo) 2) 无参有返回值函数一般用于获取某些数据或结果.(获取数字) 3) 有参无返回值函数一般利用参数完成某些特定功能.(根据传入数字生成星星矩阵) 实参与形参的传递过程,两个参数互不相干. 4) 有参有返回值函数一般用于处理数据,得到处理结果.(数据的转换.计算和统计整合数据) 2. 递归函数 1)递归需要可以跳出才有意义 2)主调函数就是被调函数 案例:  1. 等差数列     1 3 5 7 9... 2.