16.如何在切片中查找go中使用 sort.searchXXX 方法,在排序好的切片中查找指定的方法,但是其返回是对应的查找元素不存在时,待插入的位置下标(元素插入在返回下标前) 。
可以通过封装如下函数,达到目的 。
func IsExist(s []string, t string) (int, bool) {iIndex := sort.SearchStrings(s, t)bExist := iIndex!=len(s) && s[iIndex]==treturn iIndex, bExist}
17.如何初始化带嵌套结构的结构体go 的哲学是组合优于继承,使用 struct 嵌套即可完成组合,内嵌的结构体属性就像外层结构的属性即可 , 可以直接调用 。
注意初始化外层结构体时,必须指定内嵌结构体名称的结构体初始化,如下看到 s1方式报错,s2 方式正确 。
type stPeople struct {Gender boolName string}type stStudent struct {stPeopleClass int}//尝试4 嵌套结构的初始化表达式//var s1 = stStudent{false, "JimWen", 3}var s2 = stStudent{stPeople{false, "JimWen"}, 3}fmt.Println(s2.Gender, s2.Name, s2.Class)
18.切片和数组的区别数组是具有固定长度,且拥有零个或者多个,相同数据类型元素的序列 。数组的长度是数组类型的一部分,所以[3]int 和 [4]int 是两种不同的数组类型 。数组需要指定大小,不指定也会根据初始化的自动推算出大小 , 不可改变;数组是值传递 。数组是内置类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值 。在初始化后长度是固定的,无法修改其长度 。
当作为方法的参数传入时将复制一份数组而不是引用同一指针 。数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度 。数组定义:
var array [10]intvar array =[5]int{1,2,3,4,5}
切片表示一个拥有相同类型元素的可变长度的序列 。切片是一种轻量级的数据结构,它有三个属性:指针、长度和容量 。切片不需要指定大?。磺衅堑刂反荩磺衅梢酝ü槔闯跏蓟?也可以通过内置函数make()初始化。初始化时len=cap,在追加元素时如果容量cap不足时将按len的2倍扩容 。切片定义:
var slice []type = make([]type, len)
19.new和make的区别new 的作用是初始化一个指向类型的指针 (*T)。new 函数是内建函数,函数定义:func new(Type) *Type 。使用 new 函数来分配空间 。传递给 new 函数的是一个类型,不是一个值 。返回值是指向这个新分配的零值的指针 。
make 的作用是为 slice,map 或 chan 初始化并返回引用 (T) 。make 函数是内建函数 , 函数定义:func make(Type, size IntegerType) Type;第一个参数是一个类型,第二个参数是长度;返回值是一个类型 。
make(T, args) 函数的目的与 new(T) 不同 。它仅仅用于创建 Slice, Map 和 Channel,并且返回类型是 T(不是T*)的一个初始化的(不是零值)的实例 。
20.Printf()、Sprintf()、Fprintf()函数的区别用法是什么都是把格式好的字符串输出 , 只是输出的目标不一样 。
Printf(),是把格式字符串输出到标准输出(一般是屏幕 , 可以重定向) 。Printf() 是和标准输出文件 (stdout) 关联的,Fprintf 则没有这个限制 。
Sprintf(),是把格式字符串输出到指定字符串中 , 所以参数比printf多一个char* 。那就是目标字符串地址 。
Fprintf(),是把格式字符串输出到指定文件设备中 , 所以参数比 printf 多一个文件指针 FILE* 。主要用于文件操作 。Fprintf() 是格式化输出到一个stream,通常是到文件 。
21.说说go语言中的for循环for 循环支持 continue 和 break 来控制循环,但是它提供了一个更高级的break , 可以选择中断哪一个循环 for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量 。
22.Array 类型的值作为函数参数在 C/C++ 中,数组(名)是指针 。将数组作为参数传进函数时,相当于传递了数组内存地址的引用,在函数内部会改变该数组的值 。
在 Go 中 , 数组是值 。作为参数传进函数时,传递的是数组的原始值拷贝,此时在函数内部是无法更新该数组的 。
// 数组使用值拷贝传参func main() { x := [3]int{1,2,3} func(arr [3]int) {arr[0] = 7fmt.Println(arr) // [7 2 3] }(x) fmt.Println(x)// [1 2 3] // 并不是你以为的 [7 2 3]}
想改变数组 , 直接传递指向这个数组的指针类型 。
// 传址会修改原数据func main() { x := [3]int{1,2,3} func(arr *[3]int) {(*arr)[0] = 7fmt.Println(arr) // &[7 2 3] }(&x) fmt.Println(x) // [7 2 3]}
直接使用 slice:即使函数内部得到的是 slice 的值拷贝,但依旧会更新 slice 的原始数据(底层 array)
推荐阅读
- 怎么看电脑配置高低(100个电脑基础知识)
- 惠普星13air缺点_惠普星13air有哪些问题
- C# 8.0 添加和增强的功能【基础篇】
- 深度剖析Java的volatile实现原理,再也不怕面试官问了
- iptables和firewalld基础
- JavaSPI详解
- Bob 的生存概率问题
- Web自动化---解决登录页面随机验证码问题
- 数据科学学习手札146 geopandas中拓扑非法问题的发现、诊断与修复
- Python 多重继承时metaclass conflict问题解决与原理探究