Go从入门到精通(一)go语言初始
一、第一个go程序
package main import (
"fmt"
) func main(){
fmt.Println("hello world")
}
对于代码的解释
如果是为了将代码编译成一个可执行程序,那么package必须是main
如果是为了将代码编译成库,那么package则没有限制
go中所有的代码都应该隶属一个包
fmt 是go的一个系统库
fmt.println()则可以打印输出
如果想要运行程序:go run 程序名
在一个可执行程序只有一个main函数
关于注释
单行注释://
多行注释:/* */
二、go语言初识
关于定义一个变量
var 变量名 变量类型
变量名 = 值
这里需要注意:go语言中定义的变量必须被用到,否则会报错
同时定义变量和赋值可以一步完成通过: 变量名 := 值
定义一个函数
如果我们要定义一个函数,我们先看下面求和的例子:
func add(a int,b int) int {
var sum int
sum = a + b
return sum
}
这里我们需要知道,下面这种格式是被严格要求的没包括第一行的大括号不能放到下一行
func 函数名(参数1 参数1类型,参数2 参数2类型) 返回值类型 {
}
三、golang语言特性
垃圾回收
内存自动回收,不需要开发人员管理内存
开发人员专注业务实现
只需要new分配内存,不需要释放
天然高并发
- 从语言曾元支持并发,非常简单
- goroute,轻量级线程,创建成千上万goroute成为可能
- 基于CSP模型实现
关于高并发的一个简单演示:
package main import (
"fmt"
"time"
) func test_print(a int){
fmt.Println(a)
} func main(){
for i:= 0;i < 100; i ++ {
go test_print(i)
}
time.Sleep(time.Second)
}
在实现高并发的时候只需要在调用的函数前面加上go,就表示开启了并发
如果在for循环的外面不加上time.Sleep(time.Second),就会发现会少打印了,这是因为当主程序运行完之后,并不会等待线程,所以程序直接终止
channel管道
类似linux中的pipe
多个goroute之间通过channel进行通信
支持任何类型
package main import (
"fmt"
) func test_pipe(){
pipe := make(chan int,3)
pipe <- 1
pipe <- 2
pipe <- 3 fmt.Println(len(pipe))
} func main(){
test_pipe()
}
上述代码的解释:
pipe := make(chan int,3) 这里是定义一个管道pipe,go是强类型语言,所以这里声明一个管道变量pipe需要通过有三个参数,chan表示是管道,int表示管道类型,3表示管道容量
通过len(pipe)可以查看管道的的长度
如果想要从管道里获取数据
t1 :=<- pipe 这个写法等同于
var t1 int
t1 = <- pipe
fmt.Println(t1)
管道遵循的原则是先进先出,所以第一个获取的值是1
小结:如果想要给管道放入值:定义的管道pipe < - 要存入的内容
如果想要从管道中获取值:变量名 =<- 定义的管道pipe
这里强调一下go中package包的概念,一个包里的变量,在这个包里是都可以访问,但是在包之外也是有权限限制是否可以访问到,如果一个变量在一个包里是大写的,在其他包里就可以访问到,如果是小写的其他包里则访问不到。类似其他语言中的public和private
多返回值
一个函数可以返回多个值
package main
import "fmt"
func calc(a int,b int) (int,int ){
sum := a + b
avg := sum / 2
return sum,avg
}
func main(){
sum,avg := calc(100,200)
fmt.Println(sum,avg)
}
关于需要传入多个参数的时候是用括号括起来单个的情况下一般不用括号括起来,直接int,而这里是返回两个则需要 (int,int)表示返回两个整数类型值
如果有多个返回值,但是我只想返回一个值,是通过下划线方式实现,则上述代码改为:
func main(){
sum,_ := calc(100,200)
fmt.Println(sum)
}
四、包的概念
- 和python一样,把相同功能的代码放到一个目录,称之为包
- 包可以被其他包引用
- main包是用来生成可执行文件,每个程序只有一个main包
- 包的主要用途是提高代码的课复用性
关于main包中的main函数,go程序经过编译之后,运行该程序,会将编译好的二进制文件加载到内存中,会首先调用main函数,所以main函数是程序的入口函数,即必须有package main
关于包,是我们可以把一些常用的功能封装到包中,这个时候包中的每个go文件的开头则不需要package main,而是package 自定义名字 这个自定义名字是根据这个包的功能进行命名
go源码按package进行组织,并且package要放到非注释的第一行
一个程序只有一个main包,一个包中只能有一个main函数,不能重复定义
main函数是程序的执行入口
没有被引用的变量,编译的时候会报错
go的目录规范
这里举一个简单的例子:如果我们在建立一个go_project目录,通常在这个目录下我们会创建如下目录
src 存放不同的项目代码
bin 存放编译后的可执行程序
vender 存放引用的第三方库
pgk 存放静态库

我们的go环境变量中的GOPATH一般会设置为:
(我这里是路径是/users/zhaofan/go_project)
export GOPATH=/users/zhaofan/go_project
go的编译
如果我们写好了go的代码文件,我们如果测试运行可以通过:
go run 快速执行go文件
go build 编译程序,生成二进制文件
go install 安装可执行文件到bin目录下
基本命令:
go test执行单元测试或压力测试
go env 显示go相关的环境变量
go fmt 格式化源代码
我们通过下面例子理解这个编译命令的使用:
例子一

我在/users/zhaofan/go_project/src/go_dev/day01/hello目录下写了一个hello程序
现在把这个hello程序进行编译

我们在go_project目录下执行的编译命令,如果不指定编译生成的文件会直接将编译文件生成在当前目录即go_project目录下
这里需要解释的是go build 后面的路径go build go_dev/day01/hello
我们从目录结构可以看出,go_dev的上一级目录src目录并没有写,这是因为go编译的时候,会自动去GOPATH下的src目录里去找,所以这里是不需要写,同时编译的路径的最后我们只写到hello目录而不是hello.go文件
例子二
我们在/users/zhaofan/go_project/src/go_dev/day01/ 目录下建立一个goroute目录
并在goroute目录下建立两个go文件,main.go和goroute.go文件
main.go文件的代码为:
package main
import (
"time"
) func main(){
for i := 0; i < 100; i++ {
go test_goroute(i)
}
time.Sleep(time.Second)
}
goroute.go文件的代码为:
package main
import "fmt"
func test_goroute(a int){
fmt.Println(a)
}
这样我们编译的时候只需要在go_project目录下执行:
go build go_dev/day01/goroute
这样就会再go_project目录下生成一个可执行文件goroute
例子3
还是在/users/zhaofan/go_project/src/go_dev/day01/下建立一个goroute_test目录
在goroute_test目录下建立calc目录和main目录
同时在calc下建立一个sum.go文件,在main目录下建立一个main.go文件
sum.go文件代码如下:
package calc
func Add(a int,b int,c chan int){
sum := a + b
c <- sum
}
这里有个地方需要注意这里我们的sum.go是作为包写的,所以我们开头是:package calc,即package+sum.go的所在上级目录,并且是sum中定义的函数名首字母要大些(这个是必须的)这里其实是因为
我们定义的包都是要被外部的其他包调用,即我们这里定义的sum.go是要被其他包调用,这个时候只有首字母大写才能被其他包调用到
main.go文件代码如下:
package main import (
"fmt"
"go_dev/day01/goroute_test/calc"
) func main(){
pipe := make(chan int,1)
calc.Add(100,200,pipe)
res :=<- pipe
fmt.Println(res)
}
这次我们编译的时候指定编译文件生成的目录路径,命令如下:
go build -o bin/goroute_test go_dev/day01/goroute_test/main
关于单元测试例子:
单元测试的代码文件的名字格式必须是:*_test.go
例如我要写关于calc.go文件的单元测试
新建一个文件命名为:calc_test.go
这里需要知道的是开头的calc的名字并不是强制的,但是为了方便测试哪个代码文件,开头就以那个文件开头,下面是一个例子代码:
package calc import (
"testing"
)
func TestAdd(t *testing.T){
var sum int
sum = Add(5,6)
if sum != 11{
t.Fatalf("add is not right,sum:%v expected:11",sum)
}
t.Logf("add is Ok")
}
在代码中我们定义函数时候函数的名字也需要以Test开头
上述测试文件执行结果:
bogon:calc zhaofan$ go test
PASS
ok go_dev//calc .007s
bogon:calc zhaofan$ go test -v
=== RUN TestAdd
--- PASS: TestAdd (.00s)
calc_test.go:: add is Ok
PASS
ok go_dev//calc .007s
bogon:calc zhaofan$
Go的结构开发规范
好的代码规范是非常重要的,这样当你看别人代码或者别人看你的代码的时候就能很清楚的明白,下面是结构规范:
// 当前程序的包名
package main //导入其他的包
import "fmt" //常量的定义
const PI=3.14 //全局变量的声明和赋值
var name = "gopher" //一般类型声明
type newType int //结构的声明
type gopher struct{} //接口的声明
type golang interface{} //由main函数作为程序入口点启动
func main(){
fmt.Println("Hello world! 你好世界")
}
Go从入门到精通(一)go语言初始的更多相关文章
- 数据库SQL语言从入门到精通--Part 4--SQL语言中的模式、基本表、视图
数据库从入门到精通合集(超详细,学习数据库必看) 前言: 使用SQL语言时,要注意SQL语言对大小写并不敏感,一般使用大写.所有符号一定是西文标点符号(虽然是常识,但我还是提一嘴) 1.模式的定义与删 ...
- 数据库SQL语言从入门到精通--Part 3--SQL语言基础知识
数据库从入门到精通合集(超详细,学习数据库必看) 一.关系 单一的数据结构----关系 现实世界的实体以及实体间的各种联系均用关系来表示 逻辑结构----二维表 从用户角度,关系模型中数据的逻辑结构是 ...
- 数据库SQL语言从入门到精通--Part 1--SQL语言概述
数据库从入门到精通合集(超详细,学习数据库必看) 一.SQL概述 关系数据库标准语言SQL(结构化查询语言). 结构化查询语言(Structured Query Language)简称SQL,是一种特 ...
- 2015某编程网易语言vip课堂全套教程 包含post,hook入门到精通等
2015某编程网易语言vip课堂全套教程 包含post,hook入门到精通等 官方论坛弄来的 如果在官方下载需要权限的 挺不错教程 想学习易语言入门到精通 post hook js改写的可以看 ...
- c语言入门到精通怎么能少了这7本书籍?
C语言作为学编程最好的入门语言,对一个初进程序大门的小白来说是很有帮助的,学习编程能培养一个人的逻辑思维,而C语言则是公认的最符合人们对程序的认知的一款计算机语言,很多大学都选择了使用C语言作为大学生 ...
- C语言学习从入门到精通书籍,10万读者都认可
C语言程序设计从入门到精通 10万读者认可的编程图书精粹 零基础自学编程的入门图书 详解C语言编程思想和核心技术 很多初学者,对C语言.c++的概念都是模糊不清的,C语言.c++是什么,能做什么,学的 ...
- HR问了一句DB是啥?SQL是啥?DB是Database数据库,SQL是数据库语言! 然后呢? 数据库从入门到精通--入门必看!
写在前面 本文的写作知识体系来源于我的数据库老师SDAU张承明,部分知识来自于网络,我呢对知识进行了细化和添加了自己的一些看法,并且加入了一些实例帮助理解,本文不是面向SQL高手写的,可以看作是数据库 ...
- <程序员从入门到精通> -- How
定位 自己才是职业生涯的管理者,想清楚自己的发展路径: 远期的理想是什么?近期的规划是什么?今日的任务和功课又是什么? 今日之任务或功课哪些有助于近期之规划的实现,而近期之规划是否有利于远期之理想? ...
- 1、ASP.NET MVC入门到精通——新语法
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 在学习ASP.NET MVC之前,有必要先了解一下C#3.0所带来的新的语法特性,这一点尤为重要,因为在MVC项目中我们利用C#3.0的新特 ...
- 7、ASP.NET MVC入门到精通——第一个ASP.NET MVC程序
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 开发流程 新建Controller 创建Action 根据Action创建View 在Action获取数据并生产ActionResult传递 ...
随机推荐
- script defer和async一探
今天几经折腾,终于回家了,最近公司上的事忙了好一阵子,终于可以闲下来,重新在整理一下,又重新了解了一下defer和async在页面加载过程差异. 定义和用法 async 属性规定一旦脚本可用,则会异步 ...
- (转)使用string.Format需要注意的一个性能问题
今天,我在写C#代码时,突然发现一个最熟悉的陌生人 —— string.Format.在写C#代码的日子里,与它朝夕相伴,却没有真正去了解它.只知道在字符串比较多时,用它比用加号进行字符串连接效率更高 ...
- 开发一款直播APP系统软件应该有哪些功能,如何开发?
1.技术实现层面: 技术相对都比较成熟,设备也都支持硬编码.IOS还提供现成的 Video ToolBox框架,可以对摄像头和流媒体数据结构进行处理,但Video ToolBox框架只兼容8.0以上版 ...
- Laravel 5.2 教程 - 邮件
一.简介 Laravel 的邮件功能基于热门的 SwiftMailer 函数库之上,提供了一个简洁的 API.Laravel为SMTP.Mailgun.Mandrill.Amazon SES.PHP的 ...
- 高性能日志类KLog(已开源代码)
项目开源地址:https://github.com/ihambert/KLog 上回介绍了超简易日志类,但他有诸多的局限性,注定了不能作为一个网站的日志类. 那什么样的日志类才能用于网站呢.首先来假 ...
- cin 字符串输入
cin 字符串输入 在学习c的时候,关于字符串的输入,记得有 scanf("%s",s); gets(s); 还有...o.o 好想没了... scanf("%s&quo ...
- Windows10 图标重建
Windows10 图标重建 有没有遇到电脑上某个图标成了黑块,白块或者没有图呢. 那这样的话就可以使用图标重建啦. 删掉Windows10的图标文件如下图 路径: %userprofile%\App ...
- linux服务器下安装node
在百度上搜了好久,都没有完整的答案,好多都已经过时了!特留下此脚印 # 检查是否已经安装pythonrpm -qa | grep python# 查版本python# 最好是重新安装 Python推荐 ...
- Tp5.0 PHPMailer邮件发送
今天突然想起来邮件发送,就看了一下PHPmailer,其实这个用起来很简单,都是封装好的 https://github.com/PHPMailer/PHPMailer,直接下载下来之后,把他放入TP5 ...
- Echarts环形进度使用 【1 简单的使用示例】
使用中说明几点属性: hoverAnimation:false,//此处查了好久属性//控制鼠标放置在环上时候的交互//这里一个简单的示例使用Echarts 环形图使用方式//常用于统计完成进度等等 ...