【Golang 基础】Go 语言的数组
Go 语言中的数组 (示例代码) 定义数组的格式:var
Go 语言中的数组 (示例代码) 定义数组的格式:var
相比于 c/c++,golang 的一个很大的改进就是引入了 gc 机制,不再需要用户自己管理内存,大大减少了程序由于内存泄露而引入的 bug,但是同时 gc 也带来了额外的性能开销,有时甚至会因为使用不当,导致 gc 成为性能瓶颈,所以 golang 程序设计的时候,应特别注意对象的重用,以减少 gc 的压力。而 slice 和 string 是 golang 的基本类型,了解这些基本类型的内部机制,有助于我们更好地重用这些对象 slice 和 string 内部结构 slice 和 string 的内部结构可以在 $GOROOT/src/reflect/value.go 里面找到 type StringHeader struct { Data uintptr Len int } type...阅读全文
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. package main import "fmt" func main() { //s := [][]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}} //s := [][]int{{1}, {2}, {3}, {4}} //s := [][]int{{1, 2, 3, 4}, {5, 6, 7, 8}} s := [][]int{...阅读全文
square-gopher.png 数组 定义数组需要指定数组的大小和数组元素的类型 var arr1 [5]int arr2 := [3]int{1,3,5} arr3 := [...]int{2,4,6,8,10} fmt.Println(arr1,arr2,arr3) 定义数组变量如果不给初始值,int 型会默认每一个元素值为 0 使用:= 定义数组需要使用 {} 为素组时给出初始值 也可以在定义数组是让编译器根据初始化复制元素数量来决定数组的长度,[...]来代替[数组长度] golang-5.png 多维数组 var grid [4][5]int 4 个有 5 东西的集合 遍历数组 for i:= 0; i < len(arr3); i++{ fmt.Println(arr3[i]...阅读全文
变量定义 变量定义语法 使用var关键字,可放在函数内,也可放在包内 // var + 变量名 + 数据类型(有默认值) var a int var b string = "string" // 通过赋值自动判断类型 var c = true // 集中定义 var ( x = 1 y = 2 ) 使用:=定义变量,只能在函数内使用 // := 用于赋初值 a, b := 1, 2 内建变量类型(builtin) bool, string (u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr byte, rune float32, float64, complex64, complex128 强制类型转换 Golang要求强制类型转换,...阅读全文
《Go语言实战》读书笔记,未完待续,欢迎扫码关注公众号flysnow_org,第一时间看后续笔记。 书里把Map翻译为映射,我觉得太硬,所以这篇文章里,我还是用英文Map。 Map是一种数据结构,是一个集合,用于存储一系列无序的键值对。它基于键存储的,键就像一个索引一样,这也是Map强大的地方,可以快速快速检索数据,键指向与该键关联的值。 内部实现Map是给予散列表来实现,就是我们常说的Hash表,所以我们每次迭代Map的时候,打印的Key和Value是无序的,每次迭代的都不一样,即使我们按照一定的顺序存在也不行。 Map的散列表包含一组桶,每次存储和查找键值对的时候,都要先选择一个桶。如何选择桶呢?就是把指定的键传给散列函数,就可以索引到相应的桶了,进而找到对应的键值。 这种方式的好处在于...阅读全文
——引言:无论是C语言中的数组还是Go语言中的数组,数组的长度一旦确定就不能改变, 但在实际开发中我们可能事先不能确定数组的长度, 为了解决这类问题Go语言中推出了一种新的数据类型切片 什么是切片? 1.切片简单理解就是一个可变长度的数组底层的实现原理就是一个结构体, 结构体中有一个指针指向了一个数组 2.本质上所有的数据都是保存在指向的数组中的 先看一遍这个图,留个印象,一会儿再看一遍 emmmmm,再看下底层源码 //切片源码 type slice struct{ array unsafe.Pointer // 指向底层数组指针 len int // 切片长度(保存了多少个元素) cap int // 切片容量(可以保存多少个元素) } 如何创建切片 1.通过数组来创建 格式: [起始位...阅读全文
先上结论吧 select 是针对chan类型的, 所以case 只有default和chan(读/写)两种 遍历case的时候顺序不确定,但chan的优先级比default高。当有default和可执行的chan时,总是执行chan 当没有default,且无可执行的chan时,阻塞 select{}, 阻塞 开始看源码吧 scase // case 的几种类型 const ( caseNil = iota caseRecv caseSend caseDefault ) type scase struct { c *hchan // chan elem unsafe.Pointer // data element 数据元素 kind uint16 // 对应const的那几种类型 pc ui...阅读全文
在《Go语言编程》这本书和很多其他Go 编程教程中很多都提到过“Go程序员应该让一些聚合类型的零值也具有意义”的概念,我们这篇文章主要说一下有意义的零值这个话题。 在 Go 中声明变量时如果初始化表达式被省略: var 变量名字 类型 = 表达式 复制代码那么将用零值初始化变量。 以下是 Go 官方的语言参考对零值初始化机制的解释: When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no ...阅读全文
具体代码实现 /** * 冒泡算法 go 实现 */ package main import ( "fmt" "math/rand" "time" ) func main() { // 获取随机数个数 randCount := 10 randRandMax := 100 // bucketMax := randRandMax + 1 // make 创建切片,已经初始化完毕。在append的话,前面值都为0 // randList := make([]int, randCount) var randList []int // 随机数中添加种子,可以保证每次执行,产生的随机数是“真的”随机 seed := rand.New(rand.NewSource(time.Now().UnixNano(...阅读全文
JSON是一种轻量级的数据交换语言,以文字为基础,具有自我描述性且易于让人阅读。 官方提供有Json解析包:官方库文档地址 下面只说两个比较重要的函数 一、将数据编码成json字符串 函数原型 func Marshal(v interface{}) ([]byte, error) Marshal函数返回v的json编码。v是interface{}类型,任何类型都实现了空接口。 •字段的tag是“-”,那么这个字段不会输出到JSON •tag中带有自定义名称,那么这个自定义名称会出现在JSON的字段名中。 •tag中如果带有“omitempty”选项,那么如果该字段值为空,就不会输出到JSON串中 •如果字段类型是bool,string,int,int64等,而tag中带有“,string”选...阅读全文
Go语言入门——数组、切片和Map 按照以往开一些专题的风格,第一篇一般都是“从HelloWorld开始” 但是对于Go,思来想去,感觉真的从“HelloWorld”说起,压根撑不住一篇的篇幅,因为Go的HelloWorld太简单了。 1、简介 Go是什么? Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。——摘自百度百科 Github地址 https://github.com/golang/go 官网地址 https://golang.org 中文网社区 https://studygolang.com 如果需要下载安装包,可以进入https://studygolang.com/dl下载,速度较快 https://www.golang...阅读全文
周末两天拜读了飞雪无情大佬的博客,学习了Go语言,记录了一些笔记,方便之后查看。 笔记记录的内容没有按照书中的顺序,从博客里看到哪篇感兴趣就点开看看,需要系统学习Go语言的朋友可以买本书。 1. golang必备技巧:接口型函数 原始接口实现 // 定义接口 type Handler interface { Do(k, v interface{}) } func Each(m map[interface{}]interface{}, h Handler) { if m != nil && len(m) > 0 { for k,v := range m{ h.Do(k, v) } } } // 实现接口 type welcome string func (w welcome) Do(k, v ...阅读全文
1. 定义 在Go语言中切片是一种数据结构,很便于使用和管理数据集合。切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数append来实现的。这个函数可以快速且高效地增长切片。还可以通过对切片再次切片来缩小一个切片的大小。因为切片的底层内存也是在连续块中分配的,所以切片还能获得在访问速度以及垃圾回收优化等方面的好处。切片在Go语言的源码定义如下所示,由于其数据结构中有指向底层数组的指针,所以切片是一种引用类型。 // src/runtime/slice.go type slice struct { array unsafe.Pointer len int cap int } 2. 内部实现 切片是一个很小的对象,对底层数组进行了抽象。切片的数据结构有3个字段...阅读全文
参考Go语言-命令行参数(os.Args, flag包) 大部分Go程序都是没有UI的,运行在纯命令行的模式下,该干什么全靠运行参数。 这里介绍下Go语言命令行程序和他们的参数。 一、os.args 程序获取运行他时给出的参数,可以通过os包来实现。先看代码: package main import ( "fmt" "os" "strconv" ) func main () { for idx, args := range os.Args { fmt.Println("参数" + strconv.Itoa(idx) + ":", args) } } 运行起来得到的如下: $go run main.go 1 3 -X ? 参数0: /tmp/go-build116558042/command-...阅读全文
类型系统 继承 package main import ( "fmt" ) type Integer int func (a Integer) Less(b Integer) bool { return a > b } func main() { var integer Integer = 1 fmt.Println(integer.Less(0)) } // print -> true 指针运算符 * package main import ( "fmt" ) type Person struct { Id string Name string } func main() { p1 := Person{"1", "张三"} p2 := &p1 p1.Id = "2" fmt.Println...阅读全文
golang 的fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf。 # 定义示例类型和变量 type Human struct { Name string } var people = Human{Name:"zhangsan"} 普通占位符 占位符 说明 举例 输出 %v 相应值的默认格式。 Printf("%v", people) {zhangsan}, %+v 打印结构体时,会添加字段名 Printf("%+v", people) {Name:zhangsan} %#v 相应值的Go语法表示 Printf("#v", people) main.Human{Name:"zhangsan"} %T 相应值的类型的Go语法表示 Printf("%T", people...阅读全文
1 概述 Go语言是强类型语言,因此总会需要将字符串转成需要的类型。比如整型和字符串转换,字符串和布尔型的转换等。本文就介绍如何完成这些转换,以下是Go语言关于字符串转换的整理说明,主要是与切片类型的转换,和 strconv 包的使用。 2 与切片的转换 切片类型可以和字符串类型相互转换。 fmt.Println([]rune("Hello小韩说课")) // [72 101 108 108 111 23567 38889 35828 35838] fmt.Println(string([]rune{72, 101, 108, 108, 111, 23567, 38889, 35828, 35838})) // Hello小韩说课 fmt.Println([]byte("Hello")) /...阅读全文
Learn Golang in Days - Day 16-Go并发 简介 go语言支持并发,只需要使用go关键字开启goroutine即可。 goroutine是轻量级现场,goroutine由运行时进行调度管理 package main import "fmt" import "time" func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { go say("world") say("hello") } 通道channel 通道channel是用来传递数据的一个数据结构 通过可用于goroutine之间通过传递一个指...阅读全文
文地址:www.sohamkamani.com/blog/golang… 原文作者:Soham Kamani 译文地址:github.com/watermelo/d… 译者:咔叽咔叽 译者水平有限,如有翻译或理解谬误,烦请帮忙指出 首先,很容易看到数组和切片好像是同一个东西:表示列表的数据结构。然而,它们实际上彼此完全不同。 在这篇文章中,我们将探讨他们在 Go 中的差异和实现。 数组 数组是固定的数据列表。这里的重点是固定的,因为一旦设置了数组的长度,它就无法更改。 我们举一个声明了四个整数的数组的例子: arr := [4]int{3, 2, 5, 4} 复制代码长度和类型 我们在上面的例子中定义的 arr 变量的类型是 [4] int,它是一个大小为 4 的数组。这里需要注意的是,4 ...阅读全文
if语句、for语句和switch语句都属于Go语言的基本流程控制语句。 下面主要讨论for语句和switch语句,不过不讲语法规则,而是一些要注意的细节,就是“坑”。 带range子句的for语句 下面会分别讲解迭代变量和range表达式的问题。 迭代变量 对于不同种类的range表达式结果值,for语句的迭代变量的数量可以不同,下面是一个迭代变量的例子: func main() { nums := []string{"A", "B", "C", "D", "E", "F"} for i := range nums { fmt.Println(i) } } 当只有一个迭代变量的时候,数组、数组的指针、切片和字符串的元素值都是无处安放的,只能拿到按照从小到大顺序给出的一个个索引值。 如果是两...阅读全文
// 函数 // 判断在 b(s、r)中能否找到 pattern 所匹配的字符串 func Match(pattern string, b []byte) (matched bool, err error) func MatchString(pattern string, s string) (matched bool, err error) func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) // 将 s 中的正则表达式元字符转义成普通字符。 func QuoteMeta(s string) string // 示例:MatchString、QuoteMeta func main() { p...阅读全文
引用 数组、字符串和切片 Go数组中的索引问题 深入解析 Go 中 Slice 底层实现 Golang 入门 : 切片(slice) 一、数组 var a [3]int // 定义长度为3的int型数组, 元素全部为0 var b = [...]int{1, 2, 3} // 定义长度为3的int型数组, 元素为 1, 2, 3 var c = [...]int{2: 3, 1: 2} // 定义长度为3的int型数组, 元素为 0, 2, 3 var d = [...]int{1, 2, 4: 5, 6} // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6 var e = [...]int{5, 4: 1, 0, 2: 3, 2, 1: 4} // 定义长度为6的...阅读全文
golang实战笔记 一、集合类型 1.值指针和引用类型 a、go语言变量持有相应的值,列外:通道、函数、方法、映射以及切片的引用变量持有的都是引用,以即保存指针的变量。 b、函数或者方法的参数是值传递,即传递的值会被复制一次,因此: 对于布尔变量和数值类型的参数来说,很廉价,每个变量占1~8个字节; 按字符串传也廉价,64位机器16字节,32位机器8字节; 数组代价很大,使用切片替代; 注意:通过使用指针,我们可以让参数的传递成本最低,并且可修改;指针亦可以指向引用类型,但只对切片有用 2. new(Type) === &Type{} 两种语法都分配了一个Type类型的值,同时返回一个指向该值的指针;使用大括号的有点,可以为其指定初始值 3. 数组和切片 a、数组:是一个定长的序列,其中元...阅读全文
注:本文是对golang-101-hacks中文翻译。 在Go语言中,长度值是数组类型的一部分。下面的代码声明了一个数组: var array [3]int 而var slice []int声明的是一个切片类型。因此尽管是元素类型相同但长度不同的数组是不能相互赋值。例如: package main import "fmt" func main() { var a1 [2]int var a2 [3]int a2 = a1 fmt.Println(a2) } The compiler will complain: cannot use a1 (type [2]int) as type [3]int in assignment Changing "var a1 [2]int" to "var a...阅读全文
文: A complete journey with Goroutines 在Golang中如果我们想并发的处理事情,我们使用Goroutines。 但是什么是并发呢? 这儿有个例子:我正在写这篇文章突然感到口渴 ,我将停止打字然后去喝水,然后我将继续开始打字。现在,我通过时间切片的方式同时处理了2件事情(打字和喝水),这就被说成是并发工作。这里需要指明的是这两件任务(写字和喝水)不是在同一时间被处理的 。如果事情是在同一时间被处理的,那么它们就被叫做并行(例如一边玩你的手机一边吃薯片)。 因此并发是同时处理多件事情(没有必要在相同的时间做...阅读全文
关于参数传递 其实go的参数传递,核心就是一句话:go里所有参数传递都是值传递,既把参数复制一份放到函数里去用。 go的函数传参,不管参数是什么类型,都会复制一份,然后新的参数在函数内部被使用。 不像其他语言,有的时候传参只是传递一个原来参数的引用(引用和指针的区别,欢迎翻看我上上上上一篇分享),在函数内部操作变量,其实还是操作的原变量。go内不会直接的操作原变量。 关于指针 相比于C里的指针,go内部的指针一个被简化过的指针,指针可以取值获取其变量;变量可以取地址获取一个指针类型的值。 但是不可以对指针执行 地址的加减操作(unsafe.Pointer 可以,不在本次讨论范围之内)。 我觉得这个简化挺好,保留了参数传递时避免大变量的优势,又去掉了复杂性。 下面来通过实例具体说明 之所以用 ...阅读全文
数据切片的设计和注意事项 切片和数组的区别: 数组是需要指定个数的,而切片则不需要。数组赋值也可是使用如下方式,忽略元素个数,使用“...”代替 slice和array的关系十分密切,通过两者的合理构建,既能实现动态灵活的线性结构,也能提供访问元素的高效性能。当然,这种结构也不是完美无暇,共用底层数组,在部分修改操作的时候,可能带来副作用,同时如果一个很大的数组,那怕只有一个元素被切片应用,那么剩下的数组都不会被垃圾回收,这往往也会带来额外的问题。 使用make创建slice,此时golang会生成一个匿名的数组。 append操作超过了原始切片的容量,将会有一个新建底层数组的过程,那么此时再修改函数返回切片,应该不会再影响原始切片。 nil 是 interface、function、poi...阅读全文
切片与动态数组 切片是围绕着动态数组的概念构建的,可以按需自动增长或缩小,还可以通过对切片再次切片来缩小一个切片的大小。 切片的底层实现是数组,因此可以索引、迭代以及优化垃圾回收过程。 内部实现 切片是对底层数组进行了抽象,并添加了相关操作方法。 切片是包含三个字段的数据结构:array、len和cap: array是指针类型,指向底层数组 len是int64类型,表示切片的长度,即当前允许访问的长度 cap是int64类型,表示切片的容量,即切片允许增长的最大值 切片的内部实现 创建和初始化 切片有三种创建方式: 使用make函数,函数的第一个参数是切片类型,第二个参数是切片长度,第三个参数是切片容量: slice := make([]string, 3)或slice := make([]...阅读全文
package main import "fmt" func main() {arr := []int{6, 1, 2, 7, 9, 3, 4, 5, 10, 8}heapSort(arr)fmt.Println("---")fmt.Println(arr)} //堆排序func heapSort(arr []int) {//求数组长度//根据堆的规律,假设子节点的规律,假设子节点的坐标为i//左子节点坐标为2i+1,右子节点坐标为2i+2//父节点的坐标为(i-1)/2. 此处可以计算无论最后一位数字在做左子节点,还是右子节点。父节点的坐标一定是(i-1)/2。 golang中/取整//假设切片长度是len(arr),那么最后一位的坐标序号为len(arr)-1,可计算出父节点的位置为(l...阅读全文
一、流程控制// mainpackage mainimport ("fmt")func main() { x :=2switchx {case1: fmt.Print("beifeng 1")case2: fallthroughcase3: fmt.Print("beifeng 2")default: fmt.Print("beifeng 3") }}二、range遍历// main.gopackagemainimport("fmt")funcmain(){ x :="zhangsan"for_, v := range x { fmt.Printf("%c\n", v) }}三、函数左函数右返回值中间若干传入参数*传指针的值,&指针的地址函数是一等公民,也可以作为值、类型3.1 函数传值与传...阅读全文
string分割类函数123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263package mainimport ( "fmt" "strings" "unicode")/*1、func Fields(s string) []string将字符串s以空白字符分割,返回一个切片2、func FieldsFunc(s string, f func(rune) bool) []string将字符串s以满足f(r)==true的字符分割,返回一个切片3、func Split(s, sep string) []string将...阅读全文
前言 我们知道在golang中是存在指针这个概念的。对于指针很多人有点忌惮(可能是因为之前学习过C语言),因为它会导致很多异常的问题。但是很多人学习之后发现,golang中的指针很简单,没有C那么复杂。所以今天就详细来说说指针。 指针的使用 a := 1 p := &a fmt.Println(p) 输出:0xc42001c070 可以看到p就是一个指针,也可以说是a的地址。 a := 1 var p *int p = &a fmt.Println(p) 或者也可以写成这样,因为我知道,在很多人看来,看到*号才是指针(手动滑稽) a := 1 p := &a fmt.Println(*p) 输出:1 然后使用就直接通过*号就能去到对应的值了,就这么简单 指针的限制 Golang中指针之所以看...阅读全文
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wenzhou1219/article/details/81675206 学习go语言有段时间了,这门语言确实极具生产力,虽然都说简单,但是由于编程和常见的OO语言套路差别有点大,很多地方还是需要调整对已有语言的认识,这里记下遇到的一些坑,供有需要的朋友查阅。 1.main包的唯一性 传统语言中对主入口的要求是main函数,如c++/java等,只需要保证这点即可,但是在go中还需要保证main包的唯一性。 如下,在一个main包定义如下函数 package main import "fmt" func func1(){ fmt.Println("test func1") } 然后在另一个mai...阅读全文
一、熟悉Go语言运行环境、包管理工具(手动装一下Go环境并从零运行一个依赖第三方库的Go程序) go modules是官方提倡的新的包管理,乃至项目管理机制,可以不再需要GOPATH的存在。 1、go module 的初始化 golang提供了一个 环境变量“GO111MODULE”,默认值为auto,如果当前目录里有go.mod文件,就使用 go modules, 否则就使用旧的GOPATH和vendor机制,因为在modules机制下 go get 只会下载 go modules,这一行为会在以后版本中成为默认值,这里我们保持auto即可,如果你想直接使用modules而不需要从GOPATH过度,那么把“GO111MODULE”设置为 on 。 modules和传统的GOPATH不同,不...阅读全文
1 golang中的引用类型 切片,map,channel和interface2、map如何顺序读取map不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值。3 如何向main函数传参?main不能带参数,没有返回值. 可以使用flag包获取和解析命令行参...阅读全文
问题 知道golang的内存逃逸吗?什么情况下会发生内存逃逸? 怎么答 golang程序变量会携带有一组校验数据,用来证明它的整个生命周期是否在运行时完全可知。如果变量通过了这些校验,它就可以在栈上分配。否则就说它 逃逸 了,必须在堆上分配。 能引起变量逃逸到堆上的典型情况: 在方法内把局部变量指针返回 局部变量原本应该在栈中分配,在栈中回收。但是由于返回时被外部引用,因此其生命周期大于栈,则溢出。 发送指针或带有指针的值到 channel 中。 在编译时,是没有办法知道哪个 goroutine 会在 channel 上接收数据。所以编译器没法知道变量什么时候才会被释放。 在一个切片上存储指针或带指针的值。 一个典型的例子就是 []*string 。这会导致切片的内容逃逸。尽管其后面的数组可...阅读全文
函数类型也是一等的数据类型。这是什么意思呢? 这意味着函数不但可以用于封装代码、分割功能、解耦逻辑,还可以化身为普通的值,在其他函数间传递、赋予变量、做类型判断和转换等等,就像切片和字典的值那样。而更深层次的含义就是:函数值可以由此成为能够被随意传播的独立逻辑组件(或者说功能模块)。对于函数类型来说,它是一种对一组输入、输出进行模板化的重要工具,它比接口类型更加轻巧、灵活,它的值也借此变成了可被热替换的逻辑组件。 我先声明了一个函数类型,名叫Printer,注意这里的写法,在类型声明的名称右边的是func关键字,我们由此就可知道这是一个函数类型的声明。 nc右边的就是这个函数类型的参数列表和结果列表。其中,参数列表必须由圆括号包裹,而只要结果列表中只有一个结果声明,并且没有为它命名,我们就可...阅读全文
《Go语言实战》读书笔记,未完待续,欢迎扫码关注公众号flysnow_org,第一时间看后续笔记。 切片也是一种数据结构,它和数组非常相似,因为他是围绕动态数组的概念设计的,可以按需自动改变大小,使用这种结构,可以更方便的管理和使用数据集合。 内部实现切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象。因为机遇数组实现,所以它的底层的内存是连续非配的,效率非常高,还可以通过索引获得数据,可以迭代以及垃圾回收优化的好处。 切片对象非常小,是因为它是只有3个字段的数据结构:一个是指向底层数组的指针,一个是切片的长度,一个是切片的容量。这3个字段,就是Go语言操作底层数组的元数据,有了它们,我们就可以任意的操作切片了。 声明和初始化切片创建的方式有好几种,我们先看下...阅读全文
切片slice 其本身并不是数组,他指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生成 使用len()获取元素个数,cap()获取容量 一般使用make()创建 如果多个slice指向相同底层数组,其中一个的值改变会影响全部 make([]T,len,cap) 其中cap可以省略,则和len值相同 len表示存数的元素个数,cap表示容量 1234func main(){ s1 := make([]int, 10, 10) fmt.Println(s1)} Reslice Reslice 时索引以被slice的切片为准 索引不可以超过被slice的切片的容量cap()值 索引越界不会导致底层数组的重新分配而是引发错误 Appen...阅读全文
问题:对于golang项目中,随着项目的迭代,对于某个方法,如果原有的参数不够用,需要添加新的参数,又不想修改所有调用的敌法。如何做才能更好的扩展?这里提供一种方法:注:如果能不新增参数最好不要新增1、原有方法,例如:func Mytest(arg1 string, arg2 int64){ fmt.Println(arg1, arg2) }2、添加参数 args ...interface{} , 注:添加使用三个点的参数,以前的方法是不需要修改的,不会报错,相当于三个点参数args默认值是interface{}的切片。func Mytest(arg1 string, arg2 int64, args ...interface{}){ fmt.Println(arg1, arg2, args...阅读全文
// bufio 包实现了带缓存的 I/O 操作 type Reader struct { ... } // NewReaderSize 将 rd 封装成一个带缓存的 bufio.Reader 对象, // 缓存大小由 size 指定(如果小于 16 则会被设置为 16)。 // 如果 rd 的基类型就是有足够缓存的 bufio.Reader 类型,则直接将 // rd 转换为基类型返回。 func NewReaderSize(rd io.Reader, size int) *Reader // NewReader 相当于 NewReaderSize(rd, 4096) func NewReader(rd io.Reader) *Reader // bufio.Reader 实现了如下接口:...阅读全文
前言: 本专题用于记录自己(647)在Go语言方向的学习和积累。 系列内容比较偏基础,推荐给想要入门Go语言开发者们阅读。 目录如下: Go语言基础(一)—— 简介、环境配置、HelloWorld Go语言基础(二)—— 基本常用语法 Go语言基础(三)—— 面向对象编程 Go语言基础(四)—— 优质的容错处理 Go语言基础(五)—— 并发编程 Go语言基础(六)—— 测试、反射、Unsafe Go语言基础(七)—— 架构 & 常见任务 Go语言基础(八)—— 性能调优 本篇将介绍如下内容: 1.如何编写一个Go测试程序? 2.变量、常量的定义 3.基本数据类型 4.指针类型 5.运算符 6.条件与循环 7.数组与切片 8.Map 9.字符串 10.函数 (注:可根据数字快速定位本篇内容) ...阅读全文
第 19 页 在 Go 语言中,所有的变量都以值得方式传递。因为指针变量的值是所指向的内存地址,在函数间传递指针变量,是在传递这个地址值,所以依旧被看作以值得方式在传递。 第 39 页 可以访问 http://golang.org/pkg/fmt/ 或者在终端输入 godoc fmt 来了解更多关于 fmt 包的细节。 第 40 页 使用分布式版本控制系统(Distributed Version Control System,DVCS)来分享代码,如 GitHub、Launchpad 还有 Bitbucket。Go 语言的工具链本身就支持从这些网站及类似网站获取源代码。 第 44 页 go vet 命令会帮开发人员检测代码的常见错误。 第 46 页 Go 语言有两种方法为开发者生成文档。可以...阅读全文
结构体 Go语言中的结构体几乎和C语言中的结构体一模一样 都需要先定义结构体类型, 再定义结构体变量 都是用来保存一组不同类型数据的 C语言定义结构体类型的格式 struct 结构体类型名称{ 属性名称 属性类型; 属性名称 属性类型; } Go语言定义结构体类型的格式 type 结构体类型名称 struct{ 属性名称 属性类型; 属性名称 属性类型; } //定义一个结构体类型 type Person struct{ name string age int } C语言中通过结构体类型定义结构体变量, 必须拷贝struct struct 结构体类型名称 结构体变量名称; Go语言中通过结构体类型定义结构体变量, 不用拷贝struct var 结构体变量名称 结构体类型名称 //通过结构体类...阅读全文
Dig101: dig more, simplified more and know more string这么简单,我想你也一直是这样想的,没关系,我也没打算把它搞复杂。 别着急,我们先从string的拼接操作 + 开始 0x01 string对 "+" 拼接的优化 如下代码, s2, s3, s4 具体执行时有啥不同 s1 := "x" s2 := s1 + "y" + "x" + "z" s3 := s1 + "y" + s1 + "z" + s1 s4 := s1 + "y" + s1 + "z" + s1 + "z" println(s2, s3, s4) 乍一看都是字符串拼接感觉没啥不同,但是当我们用go tool compile -m来打印编译优化时发现 字面量拼接会在编译时就...阅读全文
1、数据类型底层 (一)string string类型的底层是一个C struct struct String{ byte* str; intgo len; } 成员str为字符数组,len为字符数组长度。golang的字符串是不可以变类型,对string类型的变量初始化意味着对底层结构的初始化。为什么str用byte类型不用rune类型,因为golang的for循环对字符串的遍历是基于字节的,如果有必要,可以转rune切片或者用range来迭代。 package main import ( "fmt" "unsafe" ) func main() { var str string = "hi, 张三丰~" p := (*struct { str uintptr len int })(uns...阅读全文
主要内容: 内置函数、递归函数、闭包 数组与切片 map数据结构 package介绍 内置函数 内置函数,是go语言直接支持的,可以直接使用,不用导入包: close : 主要用来关闭channel len : 求长度,比如:string、array、slice、map、channel,这些数据结构都有长度 new : 分配内存,主要用来分配值类型,比如:int、struct。返回的是指针 make : 分配内存,主要用来分配引用类型,比如:chan、map、slice append : 用来追加元素到数组、切片中 panic 和 recover : 用来做错误处理 new 的示例: package main import "fmt" func main() { a := new(int) ...阅读全文
栈 在上一部分中,我们用Go实现了最常用的数据结构-数组,并实现了数组的添加元素、删除元素、数组遍历、数组排序和数组查找等功能。 在数组中我们可以实现任意位置的添加或删除元素,但是在某些场景中,需要我们对数据的添加或删除进行进一步的限制,于是就有了栈和队列。本章将使用Go来实现栈和栈的一些基本功能。 栈是一种运算受限的线性表,对栈中数据进行操作的时候需要遵循后进先出(LIFO)原则。在栈中对元素进行入栈或出栈操作的一端叫作栈顶,另一端则为栈底。 本章中将基于Golang切片和链表两种实现方法来实现栈。 栈定义 首先定义栈接口,其中包含以下方法: Push(e ...Element):添加若干元素到栈顶 Pop() Element:弹出一个栈顶元素 Peek() Element:返回栈顶元素,...阅读全文
package main //非注释区的一个行要引入一个包,这个包的名字必须要是 main import "fmt" import "unsafe" func main(){ // 这是我的第一个 go 程序 fmt.Println("This is my first Go programma"); // myFunc1() //变量 // myFunc2() //常量 // myFunc3() //运算符 funcTest() //函数 } // 函数 funcTest(){ } //返回最大值 func max(a,b int) int{ } // 运算符 func myFunc3(){ // go 语言中的其它运算符: &(给出变量的实际地址) / *(是一个指针变量) var a =...阅读全文