go 从入门到精通(二)基本数据类型和操作符
一、文件名&关键字&标识符
- 所有go源码都是以.go结尾
- 标识符以字母或下划线开头,大小写敏感
- 下划线_是特殊标识符,用户忽略结果
- 保留关键字
- 导入包时可以设置别名
下面是保留关键字:
二、GO程序的基本结构
package main import (
"fmt"
) func main(){
fmt.Println("Hello world")
}
- 任何一个代码必须隶属一个包
- import关键字,引入其他包
- golang可执行程序,package main 并且只有一个main入口函数
- 包中函数的调用,同一个函数中可以直接调用;不同包中函数,通过包名+点+函数名进行调用
- 包访问控制规则,大写意味着这个函数或者变量可以导出的,及在其他包内是可以调用的;小写以为这个函数或者变量是私有的,包外部不能访问。
小练习1
写一个小程序,对于给定的一个数字n,求出所有两两相加等于n的组合
package main import (
"fmt"
) func add_num(n int){
for i:=0;i<=n;i++{
fmt.Printf("%d+%d=%d\n",i,n-i,n)
}
} func main(){
add_num(5)
}
小练习2
写一个小程序,包含两个包,add和main,其中add包中有两个变量:Name,和age,请问main包中如何访问Name和age?(用于理解go中大小写敏感的问题)
main包中的代码:
package main
import (
"fmt"
"go_dev/day02/kexia02/add"
) func main() {
fmt.Println(add.Name)
}
add包中的代码
package add
var Name string = "zhaofan"
var age int = 23
从结果我们可以发现我们在main包中是不能调用到add包中的age,但是是可以调用到Name
这里就是因为大小写的问题,go中的大写可以理解为其他语言中的public,小写理解为private
这里有个问题需要注意:
我们把add包中的代码改为:
package add
var Name string
var Age int Name = "zhaofan"
Age = 23
这样也是错误的写法,go作为编译型语言,必须通过函数来进行语句的执行,而不能在函数外执行语句
小练习3
开发一个小程序,使用包别名来访问包中的函数或变量
直接对上一个程序的main包进行更改
package main import (
"fmt"
a "go_dev/day02/kexia02/add"
) func main() {
fmt.Println(a.Name)
fmt.Println(a.Age)
}
小练习4
每个源文件都可以包含一个init函数,这个init函数自动被go运行框架调用,通过下面例子演示:
package main import (
"fmt"
) func init(){
fmt.Println("执行初始化函数")
} func main() {
fmt.Println("hello world")
}
运行结果是先打印了init函数的内容,后打印了main函数中的问题,所以init函数先与main函数执行
三、函数的声明和注释
函数声明
格式为:func 函数名字(参数列表)(返回值列表)
例子如下:
func add(){
}
func add(a int,b int) int{
}
func add(a int,b int) (int int){
}
注释
单行注释//
多行注释/* */
四、GO语言的数据类型和操作符
常见数据类型及分类
GO语言按照类别分为几下几种数据类型:
布尔型:true或false,例子:var b bool = true
数字类型:包括整型int和浮点float
字符串类型:这里强调一下,GO的字符串是由单个字节连接起来的Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
派生类型:这里包括指针类型,数组类型,结构化类型,Channel类型,函数类型,接口类型,Map类型
注意:
字符串的时候用双引号”“,这里也可以用反引号`,通过反引号的方式会保留你的格式,不会对你的内容做任何转义
字节的时候用单引号‘’,同样也可以通过反引号`
var cc byte = 'c' fmt.println(ccc)
var cc byte = c
fmt.println(cc)
一个会打印c的ASCII,一个会打印c
关于fmt.Printf()的用法
官网地址:https://go-zh.org/pkg/fmt/
一般
%v 相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名
%#v 相应值的Go语法表示
%T 相应值的类型的Go语法表示
%% 字面上的百分号,并非值的占位符
布尔
%t 单词 true 或 false。
整数
%b 二进制表示
%c 相应Unicode码点所表示的字符
%d 十进制表示
%o 八进制表示
%q 单引号围绕的字符字面值,由Go语法安全地转义
%x 十六进制表示,字母形式为小写 a-f
%X 十六进制表示,字母形式为大写 A-F
%U Unicode格式:U+1234,等同于 "U+%04X"
浮点数及其复合构成
%b 无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat
的 'b' 转换格式一致。例如 -123456p-78
%e 科学计数法,例如 -1234.456e+78
%E 科学计数法,例如 -1234.456E+78
%f 有小数点而无指数,例如 123.456
%g 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的0)输出
%G 根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的0)输出
字符串与字节切片
%s 字符串或切片的无解译字节
%q 双引号围绕的字符串,由Go语法安全地转义
%x 十六进制,小写字母,每字节两个字符
%X 十六进制,大写字母,每字节两个字符
指针
%p 十六进制表示,前缀 0x
通过fmt.Printf() 可以格式化输出到终端,如果想要格式化存储到变量则是fmt.Sprintf()
数字类型
数字类型包括了:
uint8(无符号8位整型,0到255)
uint16(无符号16位整型,0到65535)
uint32(无符号32位整型,0到4294967295)
unint64(无符号64位整型,0到18446744073709551615)
int8(有符号8位整型,-128到127)
int16(有符号16位整型,-32768到32767)
int32(有符号32位整型 ,-2147483648 到 2147483647)
int64(有符号64位整型 ,-9223372036854775808到9223372036854775807)
浮点型
flat32: 32位浮点型数
flag64: 64位浮点型数
complex64:32 位实数和虚数
complex128:64 位实数和虚数
类型转换
举个例子来理解: var a int = 8 转换为int32 var b int32 = int32(a)
当我们代码中设计到数据计算的时候,要保证两个数据类型完全相同,
var a int 和 var b int32 是不能直接做计算处理的,这个时候就需要用到类型转换
相关操作符
! && || 分别表示非,与,或
== 、=、!=、 <、>、<=、>=
练习1
使用math/rand生成随机整数,10个小于100的随机整数以及10个随机浮点数
package main import (
"fmt"
"math/rand"
) func rand_print(){
for i:=0;i<10;i++{
fmt.Println(rand.Int31n(100))
fmt.Println(rand.Float32())
} }
func main() {
rand_print()
}
但是这里会造成每次运行程序生成的随机数是相同的,解决方式是加入随机种子:rand.Seed(time.Now().Unix())
五、常量
常用cost修饰,代表永远是只读不能修改
const只能修饰boolean,number(int相关类型,浮点类型,complex)和string
语法
const 变量名 [变量类型] = value其中变量类型可以省略
例子
const b string = "hello"
const b int = 23
通常定义常亮的写法
const (
a = 0
b = 1
)
高级方法
const (
a = iota
b
c
)
这里自动回吧a赋值为0,后面的变量一次加1
六、变量
声明一个变量的形式是使用var关键字格式如下:
var 变量名 变量类型
关于变量的声明常用的有三种方法:
- 指定变量类型,声明变量后不赋值,使用默认值。如果是数据类型是int,默认值为0,如果数据类型是字符串string,默认值为空,如果是布尔类型默认为false
- 不指定变量类型,根据值自行判断变量类型(个人不建议这种方法,go是强类型语言,定义变量最好指定变量类型)
- 省略var关键字通过:=方式定义变量,并赋值。例子name := "zhaofan"就相当于var name string然后name = "zhaofan"
变量的作用域
在函数内部声明的变量叫做局部变量,生命周期仅限于函数内部
在函数外部生命的变量叫做全局变量,生命周期作用域整个包,如果是大写,作用域整个程序
在函数内的语句块的内的变量只在语句块,生命周期就是仅限于语句块内.这里主要指{} 括起来的语句块
通过下面的例子理解
例子1
package main import (
"fmt"
) var a string = "zhaofan" func n(){
fmt.Println(a)
}
func m(){
a := "Jack"
fmt.Println(a)
} func main(){
n()
m()
n()
}
结果会依次打印zhaofan,Jack,zhaofan
这里就是验证了函数内部的定义的变量,生命周期仅限于函数内部
如果我们把m函数中的a:="Jack"改为a = "Jack"
结果为:zhaofan,Jack,Jack
例子2
package main import (
"fmt"
)
var a string func f1(){
a := "Jack"
fmt.Println(a)
f2()
}
func f2(){
fmt.Println(a)
}
func main(){
a = "zhaofan"
fmt.Println(a)
f1()
}
这个程序的结果会打印zhaofan,Jack,zhaofan
其实这里还是要理解上面的说的关于变量的作用域
值类型和引用类型
值类型:变量直接存储值,即变量直接指向存在内存中的值。内存通常在栈中分配
值类型通常包括基本数据类型int,float,bool,string以及数组和struct
var i int = 5
var j int = i
这个时候i和j的值都为5
其实这里内存中是将i的值进行了拷贝,我们通过&获取变量的内存地址也可以看出
&i和&j 的内存地址是不同的,所以我如果在var j int = i,后继续更改i变量的值,并不会影响j的值,因为是不同的内存地址存放的值
引用类型:变量存的是一个地址,这个地址存储最终的值,内存通常在堆上分配。通过GC回收
一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。
引用类型通常包括指针,slice,map,chan等。
所以如果我们定义了两个引用类型变量像上面的值类型一样进行赋值操作则两者都会改变,因为两者的引用地址是相同的。
所以在引用类型中变量是拷贝的内存地址,而地址最终指向值
小练习1
package main import (
"fmt"
) func main() {
var a int = 100
var b chan int = make(chan int,1)
fmt.Println("a=",a)
fmt.Println("b=",b)
}
结果为:
从这里我们也可以看出值类型和引用类型的区别
小练习2
写一个小程序,交换两个整数的值
package main import (
"fmt"
) func swap(a int,b int){
a,b = b,a
fmt.Println("a=",a,"b=",b)
} func main() {
change(5,4)
}
go 从入门到精通(二)基本数据类型和操作符的更多相关文章
- iOS开发-UI 从入门到精通(二)
iOS开发-UI 从入门到精通(二)是对 iOS开发-UI 从入门到精通(一)知识点的巩固,主要以习题练习为主,增强实战经验,为以后做开发打下坚实的基础! ※开发环境和注意事项: 1.前期iOS-UI ...
- Python基本语法,python入门到精通[二]
在上一篇博客Windows搭建python开发环境,python入门到精通[一]我们已经在自己的windows电脑上搭建好了python的开发环境,这篇博客呢我就开始学习一下Python的基本语法.现 ...
- PHP从入门到精通(二)
PHP从入门到精通 之PHP中的函数 各位开发者朋友大家好,自上次更新PHP的相关知识,得到了大家的广泛支持.PHP的火爆程度不言而喻,函数作为PHP中极为重要的部分,应诸位的支持,博主继续跟进更新 ...
- MyBatis从入门到精通(二):MyBatis XML方式的基本用法之Select
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 明确需求 书中提到的需求是一个基 ...
- golang基础之二-基本数据类型和操作符
文件名&关键字&标识符 所有go源码都是以.go结尾 标识符以字母或下划线开头,大小写敏感 下划线_是特殊标识符,用户忽略结果 保留关键字 导入包时可以设置别名 下面是保留关键字: b ...
- MyBatis 入门到精通(二) SQL语句映射XML文件
MyBatis 真正强大之处就在这些映射语句,也就是它的魔力所在.对于它的强大功能,SQL 映射文件的配置却非常简单. 如果您比较SQL 映射文件配置与JDBC 代码,您很快可以发现,使用SQL 映射 ...
- SpringBoot从入门到精通二(SpringBoot整合myBatis的两种方式)
前言 通过上一章的学习,我们已经对SpringBoot有简单的入门,接下来我们深入学习一下SpringBoot,我们知道任何一个网站的数据大多数都是动态的,也就是说数据是从数据库提取出来的,而非静态数 ...
- python入门到精通[二]:基础学习(1)
摘要:Python基础学习: 注释.字符串操作.用户交互.流程控制.导入模块.文件操作.目录操作. 上一节讲了分别在windows下和linux下的环境配置,这节以linux为例学习基本语法.代码部分 ...
- Atom编辑器入门到精通(二) 插件的安装和管理
在本节中我们会学习如果安装和使用插件插件是Atom中一个非常重要的组成部分,很多功能都是以插件形式存在的.比如上篇文章中提到的目录树和设置等窗口都是通过默认安装的插件来实现的. 查看已安装的插件 打开 ...
- vue 从入门到精通(二)
上一篇总结了一些vue的理论知识,如果你没看懂的话--那返回去继续去看啊!反正我要开始第二篇了. vue提供了大量的指令,比如:v-if,v-bind,v-on--太多,多写项目,多看API,这里就不 ...
随机推荐
- JavaBean与XML转换——XStream使用笔记
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6648131.html 一:View层与Control层的数据交互 做过Web项目的人都知道,当对一个requ ...
- emplace_back() 和 push_back 的区别(转)
在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放 ...
- 事件响应的优先级、stopProgapation禁止下层组件响应
cocos2d-js没有完整的鼠标事件处理,这点比js/flash的要差一些,不过凑合着也可以用了. 一般界面编程,可以用显示列表的Node作为监听器的优先级,在上方的会比下方的高优先级. 而coco ...
- eclipse 使用tomcat运行JavaWeb项目,文件修改后为何不用重启tomcat? (运行web项目的4种方式)探究
1.情景说明 在eclipse中,为什么Java文件修改后,重启tomcat class文件才能生效? 为什么jsp修改后,不需重启tomcat就能立即生效? 为什么静 ...
- CSS知识点集锦
CSS知识点集锦 CreateTime--2016年9月29日09:43:10Author:Marydon UpdateTime--2017年3月21日08:03:13 2.CSS样式优先级问题 ...
- 〖Android〗dropbear一些操作命令备忘
相关命令行: # 启动dropbear后台运行 /data/local/tmp/dropbear \ -A -N android -I -C -G -p \ -R /data/local/tmp/au ...
- appium界面运行过程(结合日志截图分析)
appium界面运行过程: 1.启动一个http服务器:127.0.0.1:47232.根据测试代码setUp()进行初始化,在http服务器上建立一个session对象3.开始调用adb,找到连接上 ...
- 实现两个Mysql数据库同步
一. 概述 MySQL从3.23.15版本以后提供数据库复制(replication)功能,利用该功能可以实现两个数据库同步.主从模式.互相备份模式的功能.本文档主要阐述了如何在linux系 ...
- MFQ
一什么是MFQ&PPDCS?MFQ&PPDCS是由外部教练邰晓梅提出的一套测试分析和测试设计方法.MFQ将被测对象分层,针对不同层次进行测试分析和设计进行,使测试设计人员不会那么容易忘 ...
- 二维码Data Matrix简单介绍及在VS2010中的编译
Data Matrix 二维条码原名Datacode,由美国国际资料公司(International Data Matrix, 简称ID Matrix)于1989年发明.Data-Matrix二维条码 ...