Go语言基础之1--标识符、关键字、变量和常量、数据类型、Go的基本程序结构、Golang的特性...

 一、前言

当我们项目较为简单时,我们在src目录下新建一个该项目目录,里面存放源码文件即可,见下图:

当我们一个项目较为复杂时,我们可以在src目录下新建一个该项目目录,在针对该项目不同模块创建不同目录,比如说logic(逻辑)、views(图片渲染)、data(数据库)等等。

二、第一个Go程序hello world

2.1 代码

package mainimport ("fmt"
)//程序执行的入口函数
func main() {fmt.Print("hello world")fmt.Printf("hello world,%d\n ", 100)fmt.Println("hello world")
}

2.2 相关解释

♦ go语言中所有的代码(源码)不能够单独存在,必须隶属于一个包。例:第一行package main表示hello.go属于main包的。

♦ 如果是为了将代码编译成一个可执行程序,那么package必须是main;如果是为了将代码编译成库,那么package则没有限制。

♦ fmt 是go的一个系统库,所以如果我们要使用这个系统库就需要将fmp这个包导入,才能引用这个包中的函数和方法,而println就是fmt库中的一个函数,fmt.println()可以打印输出。

♦ go语言中,很多东西都是强制性的,需要去慢慢习惯。对于python等解释性语言,在函数中随便写一些语句,就可以执行了,但go不行,go语言中,程序执行的入口就是main函数(当编译完后,就是一个可执行程序,可双击执行,可执行程序的入口就是执行main函数中的内容)。 

♦ 注意:go语言中函数的花括号“{”一定要放在函数名所在行的行末。此处为强制性要求。

♦ fmt库中,print表示打印内容,printf表示格式化输出(%d表示占位符,指的是整型int,\n表示换行),println表示换行输出。

2.3 编译并执行

1、在当前终端中编译该程序实例

 

无任何输出是好事,表示程序无问题。

2、我们可以发现在当前目录已经出现了一个可执行程序

 

hello.exe就是编译后生成的可执行程序文件。

3、我们可以在当前终端目录下直接执行该可执行程序(windows环境也可以直接去所在目录双击执行即可)。

 

2.4 其他案例

上述hello world当我们在windows环境双击执行时,会发现打开后就退出了,这是正常的,程序执行完自然就退出了。此处我们我来写一个等待用户输入之后,在退出的小例子。

注意:print是打印(输出),而此处我们是要输入,用到scan,因为是输入,所以要定义一个变量来接收输入的这个值。

package mainimport ("fmt"
)//程序执行的入口函数
func main() {fmt.Print("hello world")fmt.Printf("hello world,%d\n ", 100)fmt.Println("hello world")var a intfmt.Scan(&a)  //等待用户输入然后退出
}

执行后的结果:

三、go基本命令介绍

基本命令

♦  go run 快速执行go文件,就像执行脚本一样(先编译(编译好文件放在一个临时文件下)在执行。注意:需指定要编译的源码文件

♦   go build 编译程序,生成二进制可执行文件(将当前目录下所有源码编译

♦   go install 安装可执行文件到bin目录(编译并安装,针对当前目录下所有源码

♦   go test 执行单元测试或压力测试

♦   go env 显示go相关的环境变量

♦  go fmt 格式化源代码(当我们从网络上找了些源码格式混乱时,需要针对该源码文件打开终端执行gofmt –w .)

一般来说我们的ide在我们保存时就已经将代码格式化了。

补充:

1、GOPATH下全路径编译

当处于GOPATH路径下进行编译时,要写源代码所在全路径时,不用写src,因为go中已经固定死了(默认就是往src目录下去找)。情况如下图所示(图中GOPATH为d:\project):

 

go intsall同go build一模一样。

四、go的程序结构

4.1 关于注释

单行注释://
多行注释:/* */

4.2 程序结构

♦  一个项目(目录)下所有代码文件应只属于一个包(多个会报错),也就是说一个目录下写的是一个大的功能,这些个功能只能归属于一个包。

♦  go源码按package进行组织,并且package要放到非注释的第一行

♦  一个程序(代码)只有一个main函数

♦  main函数是程序的执行入口

♦  代码是可执行程序,那么package必须是main,包是main是定死的,函数也必须是main也是定死的,否则就会报错(因为package已经声明了是main,那就表明这是可执行程序,如果此时函数不是main那就会报错。)package(包) main 和func(函数)main是一一对应的

可参考下图更好理解main

4.3 包的概念

1. 和python一样,把相同功能的代码放到一个目录,称之为包

2. 包可以被其他包引用

3. main包是用来生成可执行文件,每个程序只有一个main包

4. 包的主要用途是提高代码的可复用性

五、标识符和关键字

1、标识符是用来表示Go中的变量名或者函数名,以字母或_开头。后面跟着字母、 _或数字

如:_ab28 和ab_28就是合法的,88ab就是不合法的。

2、关键字是Go语言预先定义好的,有特殊含义的标识符。

 

 

六、变量和常量

6.1 变量

语法:var identifier type

var 变量名 变量类型

变量名 = 值

注意

1、go语言中定义的变量必须被用到,否则会报错(但是也有解决办法:如果定义的变量d未被用到,我们可以使用 _ = d 来忽略变量d

2、同时定义变量和赋值可以一步完成。

3、type可以省略不写,系统会自动根据后面给定的值进行判别

4、Go语言中变量命名推荐驼峰语法

例1:

var a int
var b string
var c bool
var d int = 8
var e string = "hello"

 

我们会发现当定义多个变量会显得很繁琐,每一个都必须写var,其实可以不用每个都写,具体见例2.

例2:

var (a int              //0 不赋值默认为0b string           //“” 不赋值默认为空c bool             //false 不赋值默认为falsed int    = 8       // 8e string = "hello" //hello
)

例3打印变量小案例:

将上述定义的变量打印出来

package mainimport ("fmt"
)var (a int              //0 不赋值默认为0b string           //“” 不赋值默认为空c bool             //false 不赋值默认为falsed int    = 8       // 8e string = "hello" //hello
)func main() {fmt.Println(a)fmt.Println(b)fmt.Println(c)fmt.Println(d)fmt.Println(e)
}

 执行结果:

补充

var a int =10 可以简写为 a :=10(:=表示声明并初始化变量

 6.2 常量

常量使用const 修饰,代表永远是只读的,不能修改。

语法:

const identifier [type] = value,其中type可以省略。

实例6-1         例1:常规写法

const b string = "hello world"
const b = "hello world"
const Pi = 3.1414926
const a = 9/3

 实例6-2         例2:优雅写法

const(a = 1b = 2c = 3
)

 实例6-3         例3:专业写法1

如果我们上述定义的的常量a、b、c是有序的,我们可以使用下面的专业写法

const (a = iotab = iotac = iota
)
# iota表示自动从0开始,第一行为0(以行为单位,和行数绑定,第一行为0,第二行为1,第三行为2),往后递增。a=0,b=1,c=2
简写为如下:一般用简写
const (a = iotabc
)

 注意:iota是与行数相绑定的,与行号相关,下面这个例子来加深印象

package mainimport ("fmt"
)const (a = 5b = iotacd = 3efg = iota
)func main() {fmt.Printf("a=%d b=%d c=%d d=%d e=%d f=%d g=%d", a, b, c, d, e, f, g)
}

执行结果:

解释:

第一行a=5

第二行b=iota,因为是第二行了了所以b=1(第一行iota=0,第二行iota=1)

第三行c,因为第二行是b = iota,所以相邻c = iota,所以c=2

第四行d=3

第五行e相邻d=3,所以e=3

第六行f也是等于3

第七行g=iota,因为是第7行了所以g=6(注意第一行是以0开始而不是1)

实例6-4         例4 专业写法2

const(a = 1 << iotabc
)
#iota可以方便的迭代一个值从0以步长1递增,0,1,2,3,4,5
结果:a=1,b=2,c=4

 七、数据类型和操作符

7.1 布尔类型

a. var b bool 和 var b bool = true 和 var b = false

b. 操作符 == 和 !=

c. 取反操作符: !b

d. && 和 || 操作符

e. 格式化输出占位符: %t

实例7-1

package mainimport ("fmt"
)func main() {var b = falsevar (c      = trued bool = false)_ = d //因为此程序d变量没有用到,此处我们将d变量赋值给_,_就相当于忽略的意思if !b {fmt.Printf("b is false\n")}if !b && c {fmt.Printf("result is true\n")}/*if b  || c == true {}*/if b || c {fmt.Printf("or operation\n")}
}

 执行结果如下:

7.2 整数和浮点数类型

a. 符号:int8(1字节)、int16(2字节)、int32(4字节)、int64(8字节)

b. 无符号:uint8、uint16、uint32、uint64

c. int和uint和操作系统平台相关(比如说:64位系统占8字节,32位系统占4字节,所以如果跨平台的话最好采用a和b带数字下标的形式,这样可扩展性比较好)

d. float32(4字节)和float64(8字节)浮点类型

e. 所有整数初始化为0,所有浮点数初始化为0.0,布尔类型初始化为false

f. Go是强类型语言,不同类型相加以及赋值是不允许的(比如说:定义为int,永远是int类型。int和int32是不同类型,不能相加也不能互相赋值)

g. 那怎么样才能实现,不同类型相加呢?

 比如:int和int32类型想要相加,那必须得做一个强制转换,转换成相同类型数据才能相加或者赋值

h. 输出占位符:整数%d, %x十六进制, %f浮点数

 补充:

1字节===8个二进制位===11111111 相当于最大值256(2^8) 如果有符号的话最大值是127

实例7-2

package mainimport ("fmt"
)func main() {var a int = 10var b int32 = 10var c intc = a + int(b)var d int = int(b)fmt.Print(a, b, c, d)fmt.Println() //不输出任何值表示换行fmt.Printf("%x\n", c)  //输出16进制c
}

 执行结果:

7.3 字符串类型

a. var str string

b. var str string = “hello world”

c. 字符串输出占位符%s

d. 万能输出占位符: %v (当不确定数据具体是什么类型时,用什么占位符时,系统自动帮我们进行转换。)

package mainimport ("fmt"
)func main() {var b string = "hello"var c = "hello"fmt.Printf("b=%v and c=%s\n", b, c)
}

 执行结果:

 

7.4 字符串的两种表示方式

a. 双引号, “”,可以包含控制字符

b. 反引号, ``,所有字符都是原样输出

c.字符必须用单引号括起来,不能用双引号,字符串用双引号。

实例7-3

package mainimport ("fmt"
)func main() {var str = "hello world\n\n" // \n是控制字符换行,""的话可以包含控制字符,输出换行var str2 = `hello \n \n \n` // ``所有字符都会原样输出fmt.Println("str=", str)fmt.Println("str2=", str2)
}

 输出结果:

实例7-4

package mainimport ("fmt"
)func test_str1() {var b string = "hello\n\n\n"var c = "hello"fmt.Printf("b=%v and c = %s\n", b, c)
}
func test_str2() {var b string = `床前明月光\n,疑是地上霜。举头望明月,低头思故乡。`fmt.Printf("b %s\n", b)
}
func test_char() {var c rune //rune用来表示一个utf8的字符c = 20320var d byte //byte表示一个字节d = 'd'//c = '你' //'你'的utf8编码是20320,所以下面代码输出‘你’var e rune = '喊'fmt.Printf("c=%c d=%c e=%c\n", c, d, e) // %c输出字符
}
func main() {test_str1()test_str2()test_char()
}

 输出结果:

补充:go语言中支持以下格式输出。

目前printf支持以下格式的输出,例如:

printf("%c",a);输出单个字符。

printf("%d",a);输出十进制整数。

printf("%f",a);输出十进制浮点数.

printf("%o",a);输出八进制数。

printf("%s",a);输出字符串。

printf("%u",a);输出无符号十进制数。

printf("%x",a);输出十六进制数。

7.5 操作符

a. 逻辑操作符, == 、 != 、 <、 <=、 >=

b. 算数操作符, +、 -、 *、 /、 %

八、 Go程序的基本结构延伸

1. 任何一个代码文件隶属于一个包

2. import 关键字,引用其他包:

import "fmt"

import("os")

通常习惯写成:

import (

"fmt"

"os"

)

3. 开发可执行程序, package main,

并且有且只有一个main入口函数。

4. 包中函数调用:

a. 同一个包中函数,直接用函数名调用

b. 不同包中函数,通过包名+点+函数名进行调用

5. 包访问控制规则:

a. 大写意味着这个函数/变量是可导出

b. 小写意味着这个函数/变量是私有的,包外部不能访问

实例8-1

目录结构:

calc:做第三方库

calc.go

package calcimport ("fmt"
)func Add(a int, b int) int {var c = a + bfmt.Printf("add result:%d\n", c)return c
}

 编译安装为静态库:

编译后的静态库:(main包为可执行包,编译后的文件为.go后缀二进制文件,main之外的包,编译后存在pkg下,后缀为.a文件)

可执行程序main.go

package mainimport ("day1/calc""fmt"
)func main() {var c intc = calc.Add(2, 3)fmt.Printf("c=%d\n", c)
}

 执行结果:

九、 Go语言特性

1. 垃圾回收

a. 内存自动回收,再也不需要开发人员管理内存

b. 开发人员专注业务实现,降低了心智负担

c. 只需要new分配内存,不需要释放

 

2. 天然并发

a. 从语言层面支持并发,非常简单(用户态实现,避免了用户态和内核态的频繁切换)

b. goroutine(协程),轻量级线程,创建成千上万个goroute成为可能(go成千上万个goroutine在用户态跑时,可能操作系统(内核)只有几千个线程再跑,java有多少个线程在用户态跑,就有多少个线程在内核态跑)

c. 基于CSP(Communicating Sequential Process)模型实现(其实就是goroutine+channel,线程之间通信借助管道)

实例9-1          

原有程序案例是:

calc.go

package calcimport ("fmt"
)func Add(a int, b int) int {var c = a + bfmt.Printf("add result:%d\n", c)return c
}

main.go 示例1

package mainimport ("day1/calc""fmt"
)func main() {var c intcalc.Add(2, 3)fmt.Printf("c=%d\n", c)
}

目前是同步执行的,如果想要异步执行,只需要如下(标红)操作即可,那样就变成多线程的了,代码示例如下:

main.go

示例2:

package mainimport ("day1/calc""fmt"
)func main() {var c intgo calc.Add(2, 3)fmt.Printf("c=%d\n", c)
}

 接下来演示效果:

如果是单线程跑,代码示例如示例1:执行结果如下:

解释:单线程跑的话,是同步的,先调函数打印出加法计算结果,然后在打出c的值。单线程是顺序输出,固定输出的。

如果是多线程跑,代码示例如示例2:实行结果如下:

解释:

go calc.Add(2, 3) 相当于起了一个线程再跑,fmt.Printf("c=%d\n", c),是另一个线程(主线程)再跑,为什么最后只打印出一个c=0,是因为主线程执行完了,退出了,其他的线程就没有机会执行了。多线程是哪一个线程调度的快,哪一个线程就优先输出,主线程优先输出的话,其他线程就没有机会执行了。

 

3. channel

a. 管道,类似unix/linux中的pipe(队列)

b. 多个goroute之间通过channel进行通信

c. 支持任何类型

实例9-2

package mainimport ("fmt"
)func main() {p := make(chan int, 3)p <- 1p <- 2var b intb = <-pfmt.Printf("b = %d\n", b)
}

输出结果:

解释:

make(chan int,3):chan就是管道类型关键字,int表示管道中放什么类型数据,3表示管道空间,也就是管道的容量

p <- 1:就表示往管道中放数据

b = <- p:表示从管道中把数据取出来给变量b

输出的b的结果为1:,是因为队列先进先出。

 

注意:

管道容量为3,当放入的数据多于3个时,就会报死锁的错误。

代码如下:

执行结果:

死锁是最近新版本加入,旧的版本会直接卡在哪里等待。

 

4. 多返回值

a. 一个函数返回多个值

实例9-3         

定义多个返回值,就要返回多个,不然会报错,都是一一对应的。

实例9-4

package mainimport ("fmt"
)func Calc(a int, b int) (int, int) {return a + b, a - b
}func main() {a1, b1 := Calc(2, 5)fmt.Printf("a1=%d b1=%d\n", a1, b1)
}

 执行结果:

 

 

转载于:https://www.cnblogs.com/forever521Lee/p/9263402.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397580.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ext springmvc mysql_基于ExtJs6前台,SpringMVC-Spring-Mybatis,resteasy,mysql无限极表设计,实现树状展示数据(treepanel)...

先从后台讲起1.表的设计2.mysql查询很容易&#xff0c;关键是要把id,text,parentId查出来/p>"http://mybatis.org/dtd/mybatis-3-mapper.dtd">SELECTbp.id,bb.name brandName,bp.name text,bp.photo_url photoUrl,bp.number,bp.add_time addTime,bp.modify_tim…

php说明代码怎么写,代码怎么写 - 起步 - PHP基础 - KK的小故事

起步 - 代码怎么写 作者&#xff1a;KK发表日期&#xff1a;2016.3.9要写PHP代码就需要建立.php后缀的文件,并且在文件里要以<?php 具体代码 ?>这样的形式来书写PHP代码我们在网站目录下新建一个叫index.php的文件,并在里面编写这样的代码:echo Hello World!;?>然后…

python中的计算符号

1、算数计算符号&#xff1a; - * /   //&#xff08;取整&#xff09;  %&#xff08;取余&#xff09;  **&#xff08;次方&#xff09; 1 >>> 682 143 >>> 9-34 65 >>> 3*46 127 >>> 16/28 8.09 >>> 9/2 10 4.5 11 >…

MySQL 索引优化全攻略

2019独角兽企业重金招聘Python工程师标准>>> 所谓索引就是为特定的mysql字段进行一些特定的算法排序,比如二叉树的算法和哈希算法,哈希算法是通过建立特征值,然后根据特征值来快速查找。而用的最多,并且是mysql默认的就是二叉树算法 BTREE,通过BTREE算法建立索引的字…

MyEclipse 14 设置文件特定的打开方式

2019独角兽企业重金招聘Python工程师标准>>> 打开windows -> preferences&#xff1b; 转载于:https://my.oschina.net/AaronDMC/blog/755481

安装安全狗后php5.5无法访问,关于安全狗的详细介绍

这篇文章主要介绍了win2008 R2安装网站安全狗提示HTTP 错误 500.21的解决方法,需要的朋友可以参考下WINDOWS 2008 R2系统IIS7.5&#xff0c;在没安装网站安全狗前一切正常&#xff0c;安装网站安全狗3.3版后&#xff0c;有部分php网站无法访问。提示如下错误&#xff1a;HTTP 错…

Android 里的数据储存

数据持久化关于数据储存,这个话题已经被反复讨论过很多次了,我是不建议把网络存储这种方式纳入到数据储存的范围的,因为这个和Android没多少关系,因此就有如下的分类: 本地储存(也称之为数据持久化,包含文件储存,SharedPreferences,SQLite储存和ContentProvider(内容提供者)) 内…

[故障解决]Mysql爆出ERROR 1044 (42000)的错误怎么办?

情况如图&#xff0c;使用dvlopenhls可以登陆到这个host&#xff0c;并且可以查看里面的tables&#xff0c;但是使用tables其中的op_flow就会报错&#xff0c;查看了很多地方&#xff0c;有人说要改密码&#xff0c;有人说要grant给权限。五花八门&#xff0c;乱七八糟。其实这…

php如何拼接数组,PHP怎么合并数组

本篇文章主要给大家介绍PHP怎么实现两个数组合并&#xff0c;并且其中一个数组的值为下标&#xff0c;另一个数组的值为对应的值。PHP进行普通数组的合并&#xff0c;相信大家都已经有所掌握。但是对于新手朋友们来说&#xff0c;合并两个数组&#xff0c;新数组的下标和值分别…

php5 mongodb,ThinkPHP5之Mongodb使用技巧

安装composer require topthink/think-mongo目录结构实践安装完成之后&#xff0c;就根据文档中的介绍开始进行codeing了&#xff0c;但是……首先我们来看下官方的使用文档配置说明不要以为这样就能够正常的使用了&#xff0c;结果远比预想中的艰难直接爆了这样的错误&#xf…

spring boot 下载

spring boot 下载 posted on 2018-07-06 22:38 zhouixi 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/1-Admin/p/9275802.html

15个Java多线程面试题

2019独角兽企业重金招聘Python工程师标准>>> 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位&#xff0c;那么你应该准备很多关于多线程的问题。在投资银行业务中多线程和并发是一个非常受欢迎的话题&…

java 将3变为03,03 Java序列化引发的血案

1、前言《手册》第 9 页 “OOP 规约” 部分有一段关于序列化的约定【强制】当序列化类新增属性时&#xff0c;请不要修改 serialVersionUID 字段&#xff0c;以避免反序列失败&#xff1b;如果完全不兼容升级&#xff0c;避免反序列化混乱&#xff0c;那么请修改 serialVersion…

《The Pomodoro Technique》

番茄工作法&#xff0c;专注当下&#xff0c;远离拖延焦虑症 简介What to solveHow to useSome applications自我总结简介 番茄工作法是简单易行的时间管理方法&#xff0c;是由弗朗西斯科西里洛于1992年创立的一种相对于GTD更微观的时间管理方法。 What to solve 各种Deadline…

XCoreRedux框架:Android UI组件化与Redux实践

XCoreRedux框架:Android UI组件化与Redux实践 author: 莫川 https://github.com/nuptboyzhb/XCoreRedux源码Demo&#xff1a;https://github.com/nuptboyzhb/XCoreRedux使用android studio打开该项目。 目录结构 demo 基于xcore框架写的一个小demoxcore XCoreRedux核心代码库…

Gigaset ME/pure/pro体验:就是这个德味

Gigaset是何方神圣&#xff1f;可能大多数人都没有听过。但如果说起西门子&#xff0c;那各位肯定就会“哦”地一声明白了。实际上&#xff0c;Gigaset就是西门子旗下的手机品牌&#xff0c;当年世界上第一部数字无绳电话就是该品牌的产物&#xff0c;所以这次Gigaset在智能手机…

IOS 资料备份

2019独角兽企业重金招聘Python工程师标准>>> 利用本地服务器边下载视频边播放 目前还没有做好&#xff0c;下面是参考资料&#xff0c;做个备份&#xff1b; 参考资料&#xff1a; http://blog.csdn.net/wxw55/article/details/17557295 http://www.code4app.com/io…

BZOJ 1854: [Scoi2010]游戏( 二分图最大匹配 )

匈牙利算法..从1~10000依次找增广路, 找不到就停止, 输出答案. ----------------------------------------------------------------------------#include<bits/stdc.h>using namespace std;const int MAXL 10009, MAXR 1000009;struct edge {int to;edge* next;} E[MA…

Android下文件的压缩和解压(Zip格式)

Zip文件结构 ZIP文件结构如下图所示&#xff0c; File Entry表示一个文件实体,一个压缩文件中有多个文件实体。 文件实体由一个头部和文件数据组&#xff0c;Central Directory由多个File header组成&#xff0c;每个File header都保存一个文件实体的偏移&#xff0c;文件最后由…

MPI多机器实现并行计算

最近使用一个系统的分布式版本搭建测试环境&#xff0c;该系统是基于MPI实现的并行计算&#xff0c;MPI是传统基于msg的系统&#xff0c;这个框架非常灵活&#xff0c;对程序的结构没有太多约束&#xff0c;高效实用简单&#xff0c;下面是MPI在多台机器上实现并行计算的过程。…