go 语言打怪升级之路~
出发~
让我们先来看一段代码
package main
import "fmt"
func main() {
fmt.Println("Hello,World!")
}
package main
这行表示文件中的所有其余代码都属于 “main” 包。
import "fmt"
表示将使用 “fmt” 包中的文本格式代码。
func main()
“main” 函数比较特殊,当程序运行时它首先运行。
fmt.Println
通过从 “fmt” 包调用 “Println” 函数来实现。
Hello,World!
这一行会显示在终端或者web浏览器上。
每个go文件最后一部分都是实际代码,通常被分割成一个或多个function(函数)。function是由一行或多行代码组成的组,可以从程序中的其他位置调用(运行)。当一个程序运行时,会寻找一个名为main的函数并首先运行它,这就是为什么将这个函数命名为main的原因。
go文件布局
可以发现几乎每个go文件中都是这三个部分。
- package 子句
package main
- 任何import语句
import "fmt"
- 实际代码
func main() {
fmt.Println("Hello,World!")
}
go 编译器带有标准格式化工具 go fmt
调用函数
fmt.Println("First argument", "Second argument")
fmt
为包名;
Println
为函数名;
函数返回值
package main
import (
"math"
"strings"
)
func main() {
math.Floor(2.75)
strings.Title("how are you")
}
这个程序不产生任何输出。
要查看函数调用的结果,需要获取返回值并将其传递给 fmt.Println
package main
import (
"fmt"
"math"
"strings"
)
func main() {
fmt.Println(math.Floor(2.75))
fmt.Println(strings.Title("how are you"))
}
字符串
字符串是一系列字节,表示文本字符,在代码中可以使用字符串字面量来定义字符串:双引号之间的文本,go将其视为字符串。
转义序列 | 值 |
---|---|
\n |
换行符 |
\t |
制表符 |
\" |
双引号 |
\\ |
反斜杠 |
示例
输入 | 输出 |
---|---|
"Hello,\nGo!" |
hello, Go! |
"Hello,\tGo!" |
Hello, Go! |
"Quotes: \"\"" |
Quotes: "" |
"Backslash: \\" |
Backslash: \ |
符文
- 字符串通常表示一系列文本字符,go的符文(
rune
)则用于表示单个字符。 - 字符串字面量由双引号
""
包围,但rune
字面量由单引号''
包围。 - go可以使用地球上任何语言的任何字符,因为go 使用Unicode标准来存储rune,rune被保存为数字代码,而不是字符本身,如果把rune传递给
fmt.Println
,会在输出中看到数字代码,而不是原始字符。 - 与字符串字面量一样,转义序列也可以用在rune字面量中,用来表示程序代码中难以包含的字符。
rune
是int32
的别名。
布尔值
布尔值只能是两个值的其中一个:true
或 false
.
他们对条件语句特别有用,条件语句只在条件为 true
或 false
时才会运行代码。
数字
还可以直接在代码中定义数字,比字符串字面量更简单:只需要输入数字即可。
go 将整数和浮点数视为不同的类型,可以使用小数点来区分整数和浮点数。
数学运算与比较
+
表示加法
-
表示减法
*
表示乘法
/
表示除法
<
与 >
比较两个值
>=
与 <=
比较两个值大于等于或小于等于
==
比较两个是否相等
!=
比较两个值是否不相等
比较的结果是一个布尔值
,true
和 false
类型
go中的值都被划分为不同的类型,这些类型指定了这些值的用途。整数可以用在数学运算中,但是字符串不可以;字符串可以大写,但是数字不能。
go是静态类型的,在程序运行之前就知道值的类型。
函数期望它们的参数具有特定的类型,返回值也具有类型(可能与参数类型相同,也可能不同)。
go是静态类型,在错误的位置使用了错误的值类型,go会告诉你。
可以将任何值传递给reflect包的TypeOf函数:
package main
import (
"fmt"
"reflect"
)
func main() {
fmt.Println(reflect.TypeOf(42))
fmt.Println(reflect.TypeOf(3.1415))
fmt.Println(reflect.TypeOf(true))
fmt.Println(reflect.TypeOf("Hello, World!"))
}
输出:
int
float64
bool
string
类型用途:
类型 | 描述 |
---|---|
int |
整型。保存数字 |
float64 |
浮点数。保存带小数部分的数字(类型名中的64是因为要用64位的数据来保存数字。这意味着四舍五入之前,float64值可以相当精确,但不能无限精确) |
bool |
布尔值。只能是true或false |
string |
字符串,通常表示文本字符的一系列数据 |
声明变量
在go中,变量是包含值的一块存储。可以使用变量声明为变量命名,使用关键字var
,后跟所需的名称以及变量将保存的值的类型 var 变量名 类型
var quantity int
var length, width float64
var customerName string
声明变量后,可以用 =
为其分配该类型的任何值。
可以在同一语句中为多个变量赋值,将变量名放在 =
左边,将相同数量的值放右边,用逗号分隔,如:
length, width = 1.2, 2.4
给变量赋值后,可以在任何使用要使用原始值的上下文中使用:
package main
import (
"fmt"
)
func main() {
//声明变量
var quantity int
var length, width float64
var customerName string
//给变量赋值
quantity = 4
length, width = 1.2, 2.4
customerName = "Domain cole"
//使用变量
fmt.Println(customerName)
fmt.Println("has ordered", quantity, "sheets")
fmt.Println("each with an area of")
fmt.Println(length*width, "squence meters")
}
输出:
Domain cole
has ordered 4 sheets
each with an area of
2.88 squence meters
若提前知道变量值是什么,可以在声明变量时一起赋值:
//声明变量并赋值
var quantity int = 4
var length, width float64 = 1.2, 2.4
var customerName string = "Domain cole"
可以为现有变量分配新值,但必须是相同类型的值。go的静态类型确保不会将错误的类型赋值给变量。
在声明变量的同时赋值,可以在变量声明中省略变量类型,分配给变量的值的类型将用作该变量的类型。
var quantity = 4
var length, width = 1.2, 2.4
var customerName = "Domain cole"
fmt.Println(reflect.TypeOf(quantity))
fmt.Println(reflect.TypeOf(length))
fmt.Println(reflect.TypeOf(width))
fmt.Println(reflect.TypeOf(customerName))
零值
若声明一个变量而没有给其赋值,则该变量将包含其类型的零值。对于数值类型,零值就是0。
int
变量零值 0
float64
变量零值 0
string
变量零值 空字符串
bool
变量零值 false
短变量声明
若声明变量时就知道初始值,可以使用短变量声明。
package main
import (
"fmt"
)
func main() {
quantity := 4
length, width := 1.2, 2.4
customerName := "Domain cole"
fmt.Println(customerName)
fmt.Println("has ordered", quantity, "sheets")
fmt.Println("each with an area of")
fmt.Println(length*width, "squence meters")
}
不需要声明变量的类型,赋给变量的值的类型成为该变量的类型。
命名规则
适用于变量、函数和类型的名称:
- 名称必须以字母开头,可以有任意数量的额外的字母和数字。
- 若变量、函数或类型的名称以大写字母开头,则认为是可导出的,可以从当前包之外的包访问它。
- 若变量、函数或类型的名称以小写字母开头,则认为该名称是未导出的,只能在当前包中使用。
以上是go语言强制执行的唯一规则。
社区约定:
- 若一个名称由多个单词组成,那么第一个单词之后的每个单词的首字母大写,且连接在一起,中间没有空格。(第一个单词首字母,只有想从包中导出时才应大写。)
- 当名称的含义在上下文中很明显时,社区惯例是缩写,用i代替index,max代替maximum等。
转换
go中的数学运算和比较运算要求包含的值应具有相同的类型,若不同,则会运行报错。 示例
var length float64 = 1.2
var width int = 2
fmt.Println("Area is", length*width)
fmt.Println("length > width?", length > width)
输出:
invalid operation: length * width (mismatched types float64 and int)
invalid operation: length > width (mismatched types float64 and int)
为变量分配新值也一样,若所赋值的类型与变量的声明类型不匹配也会报错:
将int值赋给float64变量…
var length float64 = 1.2
var width int = 2
length = width
fmt.Println(length)
报错:
cannot use width (type int) as type float64 in assignment
怎么解决呢?当然是使用转换,转换允许将值从一种类型转换为另一种类型,只需提供要将值转换成的类型,后面紧接着是在圆括号中要转换的值。
var myInt int = 2
float64(myInt)
结果是所需类型的新值。
对整型变量中的值调用TypeOf,在转换为float64后对相同的值再次调用TypeOf:
var myInt int = 2
fmt.Println(reflect.TypeOf(myInt))
fmt.Println(reflect.TypeOf(float64(myInt)))
输出:
int
float64
在进行转换时,它们可能会更改结果值,float64变量可以存储小数值,但int不可以,将float64转换为int时,小数部分会被删掉。