Go语言基础之网络编程

  互联网的核心是一系列协议,总称为”互联网协议”(InternetProtocolSuite),正是这一些协议规定了电脑如何连接和组网。我们理解了这些协议,就理解了互联网的原理。由于这些协议太过庞大和复杂,没有办法在这里一概而全,只能介绍一下我们日常开发中接触较多的几个协议。互联网的逻辑实现被分为好几层。每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持。用户接触到的只是最上面的那一层,根本不会感觉到下面的几层。要理解互联网就需要自下而上理解每一层的实现的功能。  如上图所示,互联网按照不同的模型划分会有不用的分层,但是不论按照什么模型去划分,越往上的层越靠近用户,越往下的层越靠近硬件。在软件开发中我们使用最多的是上图中将互联网划分为五个分层的模型。接下来我们一层一层的自底向上介绍一下每一层。物理层我们的电脑要与外界互联网通信,需要先把电脑连接网络,我们可以用双绞线、光纤、无线电波等方式。这就叫做”实物理层”,它就是把电脑连接起来的物理手段。它主要规定了网络的一些电气特性,作用是负责传送0...
代码星球 代码星球·2020-08-07

Go语言基础之单元测试

  Go语言中的测试依赖gotest命令。编写测试代码和编写普通的Go代码过程是类似的,并不需要学习新的语法、规则或工具。gotest命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go为后缀名的源代码文件都是gotest测试的一部分,不会被gobuild编译到最终的可执行文件中。在*_test.go文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数。类型格式作用测试函数函数名前缀为Test测试程序的一些逻辑行为是否正确基准函数函数名前缀为Benchmark测试函数的性能示例函数函数名前缀为Example为文档提供示例文档gotest命令会遍历所有的*_test.go文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。每个测试函数必须导入testing包,测试函数的基本格式(签名)如下:funcTestName(t*testing.T){//...}测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头,举几个例子:funcT...

Go语言基础之rand(随机数)包

"math/rand" 包实现了伪随机数生成器。也就是生成整形和浮点型。   该包中根据生成伪随机数是是否有种子(可以理解为初始化伪随机数),可以分为两类:  1、有种子。通常以时钟,输入输出等特殊节点作为参数,初始化。该类型生成的随机数相比无种子时重复概率较低。  2、无种子。可以理解为此时种子为1,Seek(1)。//如果无种子编译后运行的结果是定值packagemainimport("fmt""math/rand""time")funcmain(){fori:=0;i<10;i++{r:=rand.New(rand.NewSource(time.Now().UnixNano()))fmt.Printf("%d",r.Int31())}fmt.Println("")fori:=0;i<10;i++{fmt.Printf("%d",rand.Int31())}}//输出490307279188315815044484495515152675663325882934059514141740611663113020461235903925208650471...

Go语言基础之并发

  并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因。并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天)。并行:同一时刻执行多个任务(你和你朋友都在用微信和女朋友聊天)。Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作系统调度完成。Go语言还提供channel在多个goroutine间进行通信。goroutine和channel是Go语言秉承的CSP(CommunicatingSequentialProcess)并发模式的重要实现基础。在java/c++中我们要实现并发编程的时候,我们通常需要自己维护一个线程池,并且需要自己去包装一个又一个的任务,同时需要自己去调度线程执行任务并维护上下文切换,这一切通常会耗费程序员大量的心智。那么能不能有一种机制,程序员只需要定义很多个任务,让系统去帮助我们把这些任务分配到CPU上实现并发执...
代码星球 代码星球·2020-08-07

Go语言内置包之strconv

 Go语言中strconv包实现了基本数据类型和其字符串表示的相互转换。strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数:Atoi()、Itia()、parse系列、format系列、append系列。更多函数请查看官方文档。这一组函数是我们平时编程中用的最多的。Atoi()Atoi()函数用于将字符串类型的整数转换为int类型,函数签名如下。funcAtoi(sstring)(iint,errerror)如果传入的字符串参数无法转换为int类型,就会返回错误。s1:="100"i1,err:=strconv.Atoi(s1)iferr!=nil{fmt.Println("can'tconverttoint")}else{fmt.Printf("type:%Tvalue:%#v",i1,i1)//type:intvalue:100}  Itoa()Itoa()函数用于将int类型数据转换为对应的字符串表示,具体的函数签名如下。funcItoa(iint)string示例代码如下:i2:=200s2:=strconv.Itoa(i2)fmt.Print...

Go语言基础之反射

Go语言中的变量是分为两部分的:类型信息:预先定义好的元信息。值信息:程序运行过程中可动态变化的。反射是指在程序运行期对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。Go程序在运行期使用reflect包访问程序的反射信息。在上一篇博客中我们介绍了空接口。空接口可以存储任意类型的变量,那我们如何知道这个空接口保存的数据是什么呢?反射就是在运行时动态的获取一个变量的类型信息和值信息。在Go语言的反射机制中,任何接口值都由是一个具体类型和具体类型的值两部分组成的(我们在上一篇接口的博客中有介绍相关概念)。在Go语言中反射的相关功能由内置的reflect包提供,任意接口值在反射中都可以理解为由reflect.Type和reflect.Value两部分组成,并且reflect包提供了reflect.TypeOf和...
代码星球 代码星球·2020-08-07

Go语言基础之os

import"os"os包提供了操作系统函数的不依赖平台的接口。设计为Unix风格的,虽然错误处理是go风格的;失败的调用会返回错误值而非错误码。通常错误值里包含更多信息。例如,如果某个使用一个文件名的调用(如Open、Stat)失败了,打印错误时会包含该文件名,错误类型将为*PathError,其内部可以解包获得更多信息。os包的接口规定为在所有操作系统中都是一致的。非公用的属性可以从操作系统特定的syscall包获取。下面是一个简单的例子,打开一个文件并从中读取一些数据:file,err:=os.Open("file.go")//Forreadaccess.iferr!=nil{log.Fatal(err)}如果打开失败,错误字符串是自解释的,例如:openfile.go:nosuchfileordirectory文件的信息可以读取进一个[]byte切片。Read和Write方法从切片参数获取其内的字节数。data:=make([]byte,100)count,err:=file.Read(data)iferr!=nil{log.Fatal(err)}fmt.Printf("rea...
代码星球 代码星球·2020-08-07

Go语言基础之Path包与FilePath包

packagemain;import("fmt""path")//go语言path包的学习funcmain(){//返回路径的最后一个元素fmt.Println(path.Base("./a/b/c"));//如果路径为空字符串,返回.fmt.Println(path.Base(""));//如果路径只有斜线,返回/fmt.Println(path.Base("///"));//返回等价的最短路径//1.用一个斜线替换多个斜线//2.清除当前路径.//3.清除内部的..和他前面的元素//4.以/..开头的,变成/fmt.Println(path.Clean("./a/b/../"));//返回路径最后一个元素的目录//路径为空则返回.fmt.Println(path.Dir("./a/b/c"));//返回路径中的扩展名//如果没有点,返回空fmt.Println(path.Ext("./a/b/c/d.jpg"));//判断路径是不是绝对路径fmt.Println(path.IsAbs("./a/b/c"));fmt.Println(path.IsAbs("/a/b/c"));//连...

Go语言基础之runtime包

runtime调度器是非常有用的东西,关于runtime包几个方法:Gosched:让当前线程让出cpu以让其他线程运行,它不会挂起当前线程,因此当前线程未来会继续执行NumCPU:返回当前系统的CPU核数量GOMAXPROCS:设置最大的可同时使用的CPU核数Goexit:退出当前goroutine(但是defer语句会照常执行)NumGoroutine:返回真该执行和排队的任务总数GOOS:目标操作系统GOROOT:返回本机的GO路径 packagemainimport"fmt"import"runtime"funcmain(){fmt.Println("cpus:",runtime.NumCPU())//返回当前系统的CPU核数量fmt.Println("goroot:",runtime.GOROOT())//fmt.Println("NumGoroutine:",runtime.NumGoroutine())//返回真该执行和排队的任务总数fmt.Println("archive:",runtime.GOOS)//目标操作系统}运行结果cpus:12goroot:/u...
代码星球 代码星球·2020-08-07

Go语言文件操作

 os.Open()函数能够打开一个文件,返回一个*File和一个err。对得到的文件实例调用close()方法能够关闭文件。packagemainimport("fmt""os")funcmain(){//只读方式打开当前目录下的main.go文件file,err:=os.Open("./main.go")//接受文件句柄file以及error错误信息iferr!=nil{fmt.Println("openfilefailed!,err:",err)return}//关闭文件file.Close()}  为了防止文件忘记关闭,我们通常使用defer注册文件关闭语句。基本使用Read方法定义如下:func(f*File)Read(b[]byte)(nint,errerror)它接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0和io.EOF。举个例子:funcmain(){//只读方式打开当前目录下的main.go文件file,err:=os.Open("./main.go")iferr!=nil{fmt.Println("openfilefailed...
代码星球 代码星球·2020-08-07

Go语言基础之接口

 在Go语言中接口(interface)是一种类型,一种抽象的类型。interface是一组method的集合,是duck-typeprogramming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。为了保护你的Go语言职业生涯,请牢记接口(interface)是一种类型。typeCatstruct{}func(cCat)Say()string{return"喵喵喵"}typeDogstruct{}func(dDog)Say()string{return"汪汪汪"}funcmain(){c:=Cat{}fmt.Println("猫:",c.Say())d:=Dog{}fmt.Println("狗:",d.Say())}  上面的代码中定义了猫和狗,然后它们都会叫,你会发现main函数中明显有重复的代码,如果我们后续再加上猪、青蛙等动物的话,我们的代码还会一直重复下去。那我们能不能把它们当成“能叫的动物”来处理呢?像类似的例子在我们编程过程中会经常遇到:比如...
代码星球 代码星球·2020-08-07

Go语言基础之time包

 time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。time.Time类型表示时间。我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息。示例代码如下:functimeDemo(){now:=time.Now()//获取当前时间fmt.Printf("currenttime:%v",now)year:=now.Year()//年month:=now.Month()//月day:=now.Day()//日hour:=now.Hour()//小时minute:=now.Minute()//分钟second:=now.Second()//秒fmt.Printf("%d-%02d-%02d%02d:%02d:%02d",year,month,day,hour,minute,second)}  时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳(UnixTimestamp)。基于时间对象获取时间戳的示例代码如下:functimestampDemo(){now:=time.Now()...
代码星球 代码星球·2020-08-07

Go语言基础之包

 包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言为我们提供了很多内置包,如fmt、os、io等。我们还可以根据自己的需要创建自己的包。一个包可以简单理解为一个存放.go文件的文件夹。该文件夹下面的所有go文件都要在代码的第一行添加如下代码,声明该文件归属的包。package包名注意事项:一个文件夹下面只能有一个包,同样一个包的文件不能在多个文件夹下。包名可以不和文件夹的名字一样,包名不能包含-符号。包名为main的包为应用程序的入口包,编译时不包含main包的源代码时不会得到可执行文件。如果想在一个包中引用另外一个包里的标识符(如变量、常量、类型、函数等)时,该标识符必须是对外可见的(public)。在Go语言中只需要将标识符的首字母大写就可以让标识符对外可见了。举个例子,我们定义一个包名为pkg2的包,代码如下:packagepkg2import"fmt"//包变量可见性vara=100//首字母小写,外部包不可见,只能在当前包内使用//首字母大写外部包可见,可在其他包中使用constMode=1typepersonstruct{//首字母小写...
代码星球 代码星球·2020-08-07

Go语言基础之结构体

  Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。在Go语言中有一些基本的数据类型,如string、整型、浮点型、布尔等数据类型,Go语言中可以使用type关键字来定义自定义类型。自定义类型是定义了一个全新的类型。我们可以基于内置的基本类型定义,也可以通过struct定义。例如://将MyInt定义为int类型typeMyIntint通过Type关键字的定义,MyInt就是一种新的类型,它具有int的特性。类型别名是Go1.9版本添加的新功能。类型别名规定:TypeAlias只是Type的别名,本质上TypeAlias与Type是同一个类型。就像一个孩子小时候有小名、乳名,上学后用学名,英语老师又会给他起英文名,但这些名字都指的是他本人。typeTypeAlias=Type我们之前见过的rune和byte就是类型别名,他们的定义如下:typebyte=uint8typerune=int32类型别名与类型定义表面上看只有一个等号的...
代码星球 代码星球·2020-08-07

Go语言基础之指针

 任何程序数据载入内存后,在内存都有他们的地址,这就是指针。而为了保存一个数据在内存中的地址,我们就需要指针变量。比如,“永远不要高估自己”这句话是我的座右铭,我想把它写入程序中,程序一启动这句话是要加载到内存(假设内存地址0x123456),我在程序中把这段话赋值给变量A,把内存地址赋值给变量B。这时候变量B就是一个指针变量。通过变量A和变量B都能找到我的座右铭。Go语言中的指针不能进行偏移和运算,因此Go语言中的指针操作非常简单,我们只需要记住两个符号:&(取地址)和*(根据地址取值)。每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行“取地址”操作。Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等。取变量指针的语法如下:ptr:=&v//v的类型为T其中:v:代表被取地址的变量,类型为Tptr:用于接收地址的变量,ptr的类型就为*T,称做...
代码星球 代码星球·2020-08-07
首页上一页...34567...下一页尾页