Go基础语法(一)
先讲一下,写这种笔记的目的:
- 自己在学的过程中能一字一句读下来并且写出来,便于理解加深记忆,这样做比只看教程记忆会更加深刻。
- 当我某些细的点遗忘的时候我可以快速查询,因为笔记是我自己写的我知道知识点写在哪部分。
- 可以分享出来给其他热爱go的入门者或者在上学的同学看,因为这边记录的是把官方内容精简了些。
什么是Golang
Go 亦称为 Golang(译注:按照 Rob Pike 说法,语言叫做 Go,Golang 只是官方网站的网址),是由谷歌开发的一个开源的编译型的静态语言。
Golang 的主要关注点是使得高可用性和可扩展性的 Web 应用的开发变得简便容易。(译注:Go 的定位是系统编程语言,只是对 Web 开发支持较好)
Go 语言一些优点:
- 并发是语言的一部分(并非通过标准库实现),所以编写多线程程序会是一件很容易的事。后续教程将会讨论到,并发是通过 Goroutines 和 channels 机制实现的。
- Golang 是一种编译型语言。源代码会编译为二进制机器码。而在解释型语言中没有这个过程,如 Nodejs 中的 Python。
- 语言规范十分简洁。所有规范都在一个页面展示,你甚至都可以用它来编写你自己的编译器呢。
- Go 编译器支持静态链接。所有 Go 代码都可以静态链接为一个大的二进制文件(译注:相对现在的磁盘空间,其实根本不大),并可以轻松部署到云服务器,而不必担心各种依赖性。
安装
Mac OS
官网下载https://golang.org/dl/ 安装程序。双击开始安装,会将 Golang 安装到 /usr/local/go
目录下,同时 /usr/local/go/bin
文件夹也会被添加到 PATH
环境变量中。
(这里只介绍Mac OS下的安装,其他平台请自行查阅)
建立工作区
在 Mac 或 Linux 操作系统下,Go 工作区应该设置在 $HOME/go
。所以我们要在 $HOME
目录下创建 go 目录。
也可以通过设置 GOPATH ,用其他目录来作为工作区。我这边使用的ide是这个
设置GOPATH的方式:
所有 Go 源文件都应该放置在工作区里的 src 目录下。请在刚添加的 go 目录下面创建目录 src。
所有 Go 项目都应该依次在 src 里面设置自己的子目录。我们在 src 里面创建一个目录 hello 来放置整个 hello 项目。
创建上述目录之后,其目录结构如下:
go src hello hello.go
hello.go中写入代码:
package main import "fmt" func main() { fmt.Println("Hello World") }
-
使用命令go run hello.go名运行:
- 使用 go install hello 命令
当你输入 go install hello 时,go 工具会在工作区中搜索 hello 包。接下来它会在工作区的 bin 目录下,创建一个名为 hello(Windows 下名为 hello.exe)的二进制文件。运行 go install hello 后,其目录结构如下所示:
go bin hello src hello hello.go
代码中第一行:
package main ,每一个 Go 文件都应该在开头进行 package name 的声明(译注:只有可执行程序的包名应当为 main)。包(Packages)用于代码的封装与重用,这里的包名称是main。
变量
变量:变量指定了某存储单元(Memory Location)的名称,该存储单元会存储特定类型的值。在 Go 中,有多种语法用于声明变量。
package main import ( "fmt" "math" ) func main() { var age int // 变量声明 fmt.Println("my age is", age) age = 10 //变量赋值 fmt.Println("my age is", age) age = 30 //变量赋值 fmt.Println("my age is", age) var name string = "allen" // 声明变量并初始化 fmt.Println("my name is", name) var num = 29 // 可以推断类型 fmt.Println("my num is", num) var width, height int = 100, 50 // 声明多个变量 fmt.Println("width is", width, "height is", height) var a, b int //省略初始化,默认值为0 fmt.Println("width is", a, "height is", b) //一个语句中声名不同类型变量 var ( c = "jie" d = 24 e int ) fmt.Println("my c is", c, ", d is", d, "and e is", e) m, n := "allen", 29 // 简短声明 fmt.Println("m name is", m, "n is", n) //变量也可以在运行时进行赋值 q, p := 145.8, 543.8 e1 := math.Min(q, p) fmt.Println("minimum value is ", e1) }
- 声明单个变量 :var name type
- 声明变量并初始化 : var name type = initialvalue
- 类型推断(Type Inference) : 如果变量有初始值,那么 Go 能够自动推断具有初始值的变量的类型。因此,如果变量有初始值,就可以在变量声明中省略 type。例:var name = initialvalue
- 声明多个变量 : var name1, name2 type = initialvalue1, initialvalue2。
- 一个语句中声明不同类型的变量 :
var (
name1 = initialvalue1,
name2 = initialvalue2
) - 简短声明 : name := initialvalue,
简短声明要求 := 操作符左边的所有变量都有初始值。
简短声明的语法要求 := 操作符的左边至少有一个变量是尚未声明的。 - 由于 Go 是强类型(Strongly Typed)语言,因此不允许某一类型的变量赋值为其他类型的值。
类型
基本类型:
- bool
- 数字类型
int8, int16, int32, int64, int
uint8, uint16, uint32, uint64, uint
float32, float64
complex64, complex128
byte
rune - string
有符号整型:
int:根据不同的底层平台(Underlying Platform),表示 32 或 64 位整型。除非对整型的大小有特定的需求,否则你通常应该使用 int 表示整型。
在 Printf 方法中,使用%T
打印变量类型。
Go 的 unsafe 包提供了一个 Sizeof 函数,该函数接收变量并返回它的字节大小。
func main() { a := true b := false fmt.Println("a:", a, "b:", b) c := a && b //仅当 a 和 b 都为 true 时,操作符 && 才返回 true fmt.Println("c:", c) d := a || b //当 a 或者 b 为 true 时,操作符 || 返回 true fmt.Println("d:", d) var a1 int = 89 b1 := 95 fmt.Println("a1 is", a1, "and b is", b1) fmt.Printf("type of a is %T, size of a is %d", a1, unsafe.Sizeof(a1)) // a 的类型和大小 fmt.Printf("\ntype of b is %T, size of b is %d", b1, unsafe.Sizeof(b1)) // b 的类型和大小 }
在32位系统下,字节大小为4,64位下,字节大小为8。
无符号整型
uint:根据不同的底层平台,表示 32 或 64 位无符号整型。
浮点型
float32:32 位浮点数
float64:64 位浮点数
package main import ( "fmt" ) func main() { a, b := 5.67, 8.97 //a 和 b 的类型根据赋值推断得出,float64 是浮点数的默认类型 fmt.Printf("type of a %T b %T\n", a, b) sum := a + b diff := a - b fmt.Println("sum", sum, "diff", diff) no1, no2 := 56, 89 fmt.Println("sum", no1+no2, "diff", no1-no2) }
a 和 b 的类型根据赋值推断得出,float64 是浮点数的默认类型。
复数类型
complex64:实部和虚部都是 float32 类型的的复数。
complex128:实部和虚部都是 float64 类型的的复数。
其他数字类型
byte 是 uint8 的别名。
rune 是 int32 的别名。
string 类型
在 Golang 中,字符串是字节的集合。如果你现在还不理解这个定义,也没有关系。我们可以暂且认为一个字符串就是由很多字符组成的。后面会在一个教程中深入学习字符串。
package main import ( "fmt" ) func main() { first := "Zhao" last := "Alle" name := first +" "+ last fmt.Println("My name is",name) }
类型转换
Go 有着非常严格的强类型特征。Go 没有自动类型提升或类型转换。
package main import ( "fmt" ) func main() { i := 55 //int j := 67.8 //float64 sum := i + int(j) //j is converted to int fmt.Println(sum) q := 10 var w float64 = float64(q) // 若没有显式转换,该语句会报错 fmt.Println("w", w) }
把 v 转换为 T 类型的语法是 T(v)。
赋值的情况也是如此。把一个变量赋值给另一个不同类型的变量,需要显式的类型转换。
常量
定义:在 Go 语言中,术语"常量"用于表示固定的值。
使用关键字 const
表示常量。
package main func main() { const a = 55 // 允许 a = 89 // 不允许重新赋值 }
- 常量不能再重新赋值为其他的值。因此上面的代码将不能正常工作,它将出现一个编译错误: cannot assign to a
- 常量的值会在编译的时候确定。因为函数调用发生在运行时,所以不能将函数的返回值赋值给常量。
字符串常量
const a = "Hello World"
上面的例子,我们把 Hello World 分配给常量 a。现在常量 a 是没有类型的。
无类型的常量有一个与它们相关联的默认类型(上边默认类型是string),并且当且仅当一行代码需要时才提供它。在声明中 var b = "Sam" , b 需要一个类型,它从字符串常量 Sam 的默认类型中获取。
创建一个带类型的常量:const c string = "Hello World"
常量c就是一个string类型的。
Go 是一个强类型的语言,在分配过程中混合类型是不允许的。
布尔常量
布尔常量和字符串常量用法相同,他们是两个无类型的常量 true 和 false。
package main func main() { const trueConst = true type myBool bool var defaultBool = trueConst // 允许 var customBool myBool = trueConst // 允许 defaultBool = customBool // 不允许 }
数字常量
包含整数、浮点数和复数的常量
func main() { const a = 5 var intVar int = a var int32Var int32 = a var float64Var float64 = a var complex64Var complex64 = a fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var) }
常量a 的值是 5 ,a 的语法是通用的(它可以代表一个浮点数、整数甚至是一个没有虚部的复数),因此可以将其分配给任何兼容的类型。这些常量的默认类型可以被认为是根据上下文在运行中生成的。 var intVar int = a 要求 a 是 int,所以它变成一个 int 常量。 var complex64Var complex64 = a 要求 a 是 complex64,因此它变成一个复数类型。
数字表达式
func main() { var a = 5.9/8 fmt.Printf("a's type %T value %v",a, a) }
在上面的程序中, 5.9 在语法中是浮点型,8 是整型,5.9/8 是允许的,因为两个都是数字常量。除法的结果是 0.7375 是一个浮点型,所以 a 的类型是浮点型。
如果内容对你有帮助,记得关注作者给个赞哦~,后续会持续更新。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Dubbo 源码分析 - 服务导出
1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程。Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑。整个逻辑大致可分为三个部分,第一是前置工作,主要用于检查参数,组装 URL。第二是导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程。第三是向注册中心注册服务,用于服务发现。本篇文章将会对这三个部分代码进行详细的分析,在分析之前,我们先来了解一下服务的导出过程。 Dubbo 支持两种服务导出方式,分别延迟导出和立即导出。延迟导出的入口是 ServiceBean 的 afterPropertiesSet 方法,立即导出的入口是 ServiceBean 的 onApplicationEvent 方法。本文打算分析服务延迟导出过程,因此不会分析 afterPropertiesSet 方法。下面从 onApplicationEvent 方法说起,该方法收到 Spring 容器的刷新事件后,会调用 export 方法执行服务导出操作。服务导出之前,要进行对一系列的配置进行检查,以及生成 URL。准...
- 下一篇
快学 Go 语言第 2 课 —— 变量什么的最讨厌了
任何一门语言里面最基础的莫过于变量了。如果把内存比喻成一格一格整齐排列的储物箱,那么变量就是每个储物箱的标识,我们通过变量来访问计算机内存。没有变量的程序对于人类来说是可怕的,需要我们用数字位置来定位内存的格子,人类极不擅长这样的事。这就好比一岁半左右的幼儿还没有学会很多名词,只能用手来对物体指指点点来表达自己的喜好。变量让程序逻辑有了丰富的表达形式。 定义变量的三种方式 Go 语言的变量定义有多种形式,我们先看最繁琐的形式 package mainimport "fmt"func main() {var s int = 42 fmt.Println(s) } -------------42 注意到我们使用了 var 关键字,它就是用来显式定义变量的。还注意到在变量名称 s 后面声明了变量的类型为整形 int,然后再给它赋上了一个初值 42。上面的变量定义可以简化,将类型去掉,因为编译器会自动推导变量类型,效果也是一样的,如下 package mainimport "fmt"func main() {var s = 42 fmt.Println(s) } ---------------...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Docker快速安装Oracle11G,搭建oracle11g学习环境