一、go程序基础
1、文件名
go语言文件名命名规范:
- go语言的文件名必须以
.go
结尾。 - go语言的文件名必须以小写字母开头,否则会报错。
- go语言的文件名不能包含空格,否则会报错。
- go语言的文件名不能包含特殊字符,否则会报错。
- go语言的文件名不能包含中文,否则会报错。
- go语言的文件名不能包含大写字母,否则会报错。
2、关键字
关键字是指编程语言中预先定义好的具有特殊含义的标识符,关键字和保留字都不建议用作变量名。
(1)Go语言中25个关键字
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
(2)Go语言中37个保留字
Constants: true false iota nil
Types: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
Functions: make len cap new append copy close delete
complex real imag
panic recover
3、标识符
标识符以字母或下划线开头,后面可以跟任意数量的字母、数字或下划线。
- 大小写敏感:如
age
和Age
是两个不同的标识符。 - 不能包含空格。如
my age
是非法的标识符。 - 不能包含特殊字符,如
@
、#
、$
等。 - 仅能包含字母、数字和下划线。如
my-age
是非法的标识符。 - 不能是Go语言的关键字。如
func
、if
、else
等是非法的标识符。 - 不能是Go语言的预定义标识符。如
true
、false
、nil
等是非法的标识符。 - 不能是Go语言的内置标识符。如
append
、cap
、close
等是非法的标识符。 - 不能是Go语言的保留标识符。如
break
、case
、chan
等是非法的标识符。 - 不能是Go语言的类型名。如
int
、string
、bool
等是非法的标识符。 - _(下划线)是一个特殊的标识符,它可以用来接收任何值,但是它本身不占用内存空间,也不会分配内存空间。
4、基本结构
Go语言的基本结构如下:
package main
import "fmt"
func main() {
fmt.Println("Hello, World! ")
}
- 任何一个代码文件都必须以
package
关键字开头,表示该文件属于哪个包。 import
关键字用于导入其他包。
import "fmt"
import ("time")
// 通常情况下,我们只需要导入一个包,但是如果导入多个包,可以使用括号将多个包括起来
import (
"fmt"
"time"
)
- golang可执行程序的入口是
main
函数,main
函数是main
包中的一个特殊函数。
func main() {
fmt.Println("Hello, World! ")
}
- 包中函数调用:
- 同一个包中的函数可以直接调用。
- 不同包中的函数需要通过
import
导入后才能调用。通过包名.函数名()
的方式调用。
package main
import "fmt"
func main() {
// 包中函数调用
test()
}
func test() {
fmt.Println("test()...")
}
- 包访问权限:
- 如果标识符(变量、常量、函数、类型、接口等)的首字母是大写的,那么就表示对外部包可见(暴露的,公有的)。
- 如果标识符的首字母是小写的,那么就表示对外部包不可见(非暴露的,私有的)。
package main
import "fmt"
func main() {
// 包访问权限
test()
}
func test() {
fmt.Println("test()...")
}
(1)练习
练习1:写一个程序,对于给定一个数字n,求出所有两两相加等于n的组合。
package main
import "fmt"
func main() {
// 练习
var n int
fmt.Println("请输入一个数字:")
fmt.Scanln(&n) // 从键盘输入一个数字,赋值给n
for i := 1; i <= n; i++ { // i从1开始,到n结束
for j := 1; j <= n; j++ { // j从1开始,到n结束
if i+j == n {
fmt.Printf("%d + %d = %d\n", i, j, n)
}
}
}
}
/*
PS D:\GolangProjects\src\crm> go run test1.go
请输入一个数字:
5
1 + 4 = 5
2 + 3 = 5
3 + 2 = 5
4 + 1 = 5
*/
(2)练习
包别名应用,开发一个程序,使用包别名访问包中的函数。
创建出如下目录结构:
└─example2
├─add\add.go
├─main\main.go
└─test\test.go
代码如下所示:
// test\test.go:
package test
import (
"fmt"
)
var Name string = "this is test package"
var Age int = 18
func init() {
fmt.Println("test package init")
fmt.Println("test package Name=", Name)
fmt.Println("test package Age=", Age)
Age = 10
fmt.Println("test package Age=", Age)
}
// add\add.go:
package add
import (
_ "crm/example2/test"
"fmt"
)
func init() {
Name = "this is add package"
Age = 22
fmt.Println("add package init")
fmt.Println("add package Name=", Name)
fmt.Println("add package Age=", Age)
}
var Name string = "this is add package XXXX"
var Age int = 35
// main\main.go:
package main
import (
a "crm/example2/add" // import add package
"fmt"
)
func main() {
fmt.Println("main.package.Name=", a.Name)
fmt.Println("main.package.Age=", a.Age)
}
编译执行效果:
PS D:\GolangProjects\src\crm> go build -o example2.exe .\example2\main
PS D:\GolangProjects\src\crm> .\example2.exe
test package init
test package Name= this is test package
test package Age= 18
test package Age= 10
add package init
add package Name= this is add package
add package Age= 22
main.package.Name= this is add package
main.package.Age= 22
二、数据类型
Go是一种静态类型的编程语言,它有一些基本数据类型。
1、基本数据类型
- bool:布尔类型,表示真或假,取值为true或false。
- string:字符串类型,表示一串字符,用双引号或反引号括起来。
- int, int8, int16, int32, int64:整数类型,分别表示8位、16位、32位和64位的有符号整数。
- uint, uint8, uint16, uint32, uint64:无符号整数类型,分别表示8位、16位、32位和64位的无符号整数。
- float32, float64:浮点数类型,分别表示单精度和双精度浮点数。
- complex64, complex128:复数类型,分别表示32位和64位的复数。
- byte:等同于uint8类型。
- rune:等同于int32类型,用于表示Unicode码点。
除了这些基本数据类型外,Go还有一些复合类型,如数组、切片、映射、结构体等。
package main
import "fmt"
func main() {
// 整型
fmt.Println(666)
fmt.Println(6 + 9)
fmt.Println(6 - 9)
fmt.Println(6 * 9)
fmt.Println(16 / 9) // 商
fmt.Println(16 % 9) // 余数
// 字符串类型,特点:通过双引号
fmt.Println("库里")
fmt.Println("钓鱼要掉刀鱼,刀鱼到岛上钓")
fmt.Println("alex" + "SB")
//fmt.Println("alex" + 666)
fmt.Println("alex" + "666")
// 对比
fmt.Println("1" + "2") // 结果:"12"
fmt.Println(1 + 2) // 结果:3
// 布尔类型,真假
fmt.Println(1 > 2) // false 假
fmt.Println(1 < 2) // true 真
fmt.Println(1 == 2)
fmt.Println(1 >= 2)
fmt.Println("allen" == "dcm")
// 超前
if 2 > 1 {
fmt.Println("2大于1")
} else {
fmt.Println("2不大于1")
}
}
三、变量
变量来历:变量是计算机语言中最基本的存储单元,其本质是将内存中的一块区域进行命名,开辟出来的内存区域可以用来存储数据。
变量类型:变量的类型决定了变量的内存大小和布局,该变量能存储的值的范围和存储方式。常见的变量类型有:整型、浮点型、布尔型、字符串型等。
1、变量的声明
Go语言中变量需要先声明后使用,同一个作用域内的变量名不能重复。
且Go语言中的变量声明后必须使用,否则编译不通过。
(1)变量声明格式
-
声明 + 赋值
var sd string = "kobe" fmt.Println(sd) var age int = 73 fmt.Println(age) var flag bool = true fmt.Println(flag)
-
先声明后赋值
// 声明了一个字符类型变量 sd var sd string // 给sd变量赋值 sd = "james" fmt.Println(sd)
(2)声明变量的意义?
-
编写代码省事
// 文本,请将文本输出3次:"伤情最是晚凉天,憔悴斯人不堪怜。" var message string = "伤情最是晚凉天,憔悴斯人不堪怜。" fmt.Println(message) fmt.Println(message) fmt.Println(message)
-
存储结果,方便之后使用
// 存储结果,方便之后使用 var v1 int = 99 var v2 int = 33 var v3 int = v1 + v2 var v4 int = v1 * v2 var v5 int = v1 + v2 + v3 + v4 fmt.Println(v1, v2, v3, v4, v5)
-
存储用户输入的值
var name string fmt.Scanf("%s", &name) // 用户输入字符串并赋值给name变量 if name == "curry" { fmt.Println("用户名输入正确") } else { fmt.Println("用户名输入失败") }
(3)变量的初始化
Go语言在声明变量时,会自动对变量对应的内存区域进行初始化,每个变量会被初始化成其类型的默认值。
例如:整型的默认值是0,字符串的默认值是空字符串,布尔类型的默认值是false。
var name string
var age int
var isOk bool
fmt.Println(name, age, isOk) // 输出:"" 0 false
也可以在声明变量时,对变量进行初始化,例如:
var name string = "kobe"
var age int = 41
var isOk bool = true
fmt.Println(name, age, isOk) // 输出:kobe 41 true
(4)变量的类型推导
在声明变量时,如果没有显式指定变量的类型,那么编译器会自动根据变量的值推导出变量的类型。
var name = "kobe"
var age = 41
var isOk = true
fmt.Println(name, age, isOk) // 输出:kobe 41 true
(5)短变量声明
在函数内部,可以使用短变量声明方式声明并初始化变量,格式:变量名 := 表达式
。
注意:短变量声明方式只能在函数内部使用。
func main() {
name := "kobe"
age := 41
isOk := true
fmt.Println(name, age, isOk) // 输出:kobe 41 true
}
2、变量名要求
-
【要求】变量名必须只包含:字母、数字、下划线
var %1 string,错误 var $ string,错误
-
【要求】数字不能开头
var 1 string 错误 var 1name string 错误 var _ string 正确
-
【要求】不能使用go语言内置的关键字
var var string = "南通州北通州南北通州通南北" 错误
-
建议
- 变量名见名知意:name/age/num ; v1、v2、v3
- 驼峰式命名:myBossName / startDate / endDate
3、变量简写
-
声明+赋值
var name string = "战狼" // 标准声明格式 var name = "战狼" // 简写格式 name := "战狼" // 推荐使用
-
先声明再赋值
// 先声明 var name string var message string var data string // 批量声明 var name,message,data string // 再赋值 name = "战鹰" message = "中奖了" data = "中了5000w"
-
因式分解(批量声明变量),例如:声明5个变量,分别有字符串、整型
var ( name = "allen" age = 18 hobby = "basketball" salary = 1000000 gender string // 只声明但不赋值,有一个默认: "" length int // 只声明但不赋值,有一个默认: 0 sb bool // 只声明但不赋值,有一个默认: false ) fmt.Println(name, age, hobby, salary, gender,length,sb)
扩展:go编译器会认为声明变量不使用 就是耍流氓。
4、作用域
如果我们定义了大括号,那么在大括号中定义的变量。
- 不能被上级使用。
- 可以在同级使用。
- 可以再子级使用。
package main
import "fmt"
func main() {
name := "武沛齐"
fmt.Println(name)
if true {
age := 18
name := "alex"
fmt.Println(age)
fmt.Println(name)
}
fmt.Println(name)
}
5、全局变量和局部变量
- 全局变量,未写在函数中的变量称为全局变量;不可以使用
v1:=xx
方式进行简化;可以基于因式分解方式声明多个变量;项目中寻找变量时最后一环。 - 局部变量,编写在{}里面的变量;可以使用任意方式简化;可以基于因式分解方式声明多个变量;
package main
import "fmt"
// 全局变量(不能以省略的方式)
var school string = "hbkj" // 可以
//var school = "hbkj" // 可以
//school := "hbkj" // 不可以(仅能在函数中使用)
var (
v1 = 123
v2 = "你好"
v3 int
)
func main() {
name := "hqs" // 局部变量
fmt.Println(name)
if true {
age := 18 // 局部变量
name := "alex" // 局部变量
fmt.Println(age)
fmt.Println(name)
}
fmt.Println(name)
fmt.Println(school)
fmt.Println(v1, v2, v3)
}
6、匿名变量
在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量(anonymous variable)。匿名变量用一个下划线 _
表示。
匿名变量的特点是一个下画线_
,_
本身就是一个特殊的标识符,被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。
func foo() (int, string) {
return 10, "Q1mi"
}
func main() {
x, _ := foo()
_, y := foo()
fmt.Println("x=", x) // x= 10
fmt.Println("y=", y) // y= Q1mi
}
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。(在 Lua
等编程语言里,匿名变量也被叫做哑元变量。)
注意事项:
- 函数外的每个语句都必须以关键字开始(
var
、const
、func
等) :=
不能使用在函数外。_
多用于占位,表示忽略值。
7、赋值及内存相关
变量重新赋值时,同一代码块,内存地址不变。不同代码块,内存地址会变。
func main() {
var a int = 10
var b string = "hello"
var c bool = true
fmt.Println(a, &a) // 10 0xc0000160b8
fmt.Println(b, &b) // hello 0xc00004e050
fmt.Println(c, &c) // true 0xc0000160d0
a = 20
b = "world"
c = false
fmt.Println(a, &a) // 20 0xc0000160b8
fmt.Println(b, &b) // world 0xc00004e050
fmt.Println(c, &c) // false 0xc0000160d0
}
string、int、bool这三种数据类型,如果遇到变量的赋值则会拷贝一份。
package main
import "fmt"
func main() {
name := "hqs"
nickname := name
fmt.Println(name, &name) // hqs 0xc00004e050
fmt.Println(nickname, &nickname) // hqs 0xc00004e060
name = "allen"
fmt.Println(name, &name) // allen 0xc00004e050
fmt.Println(nickname, &nickname) //hqs 0xc00004e060
}
四、常量
常量使用 const
关键字定义,用于存储不会改变的数据。
const
只能修饰boolean、数字(整数、浮点数、复数)和字符串类型。
常量语法格式:
const identifier [type] = value // 其中 type 可以省略不写。
示例:
package main
import "fmt"
const b string = "abc" // 定义字符串常量,完整格式
const c = "abcd" // 简化格式,自动推导类型
const Pi = 3.1415926 // 定义浮点型常量
const a = 9 / 3 // 定义整型常量,可以使用运算表达式
// const d = getValue() // 常量不能函数赋值,不能使用内置函数,不能使用运行期间才能确定结果的表达式
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
// fmt.Println(d)
fmt.Println(Pi)
}
/*
3
abc
abcd
3.1415926
*/
1、因式分解
因式分解可以将一个复杂的常量定义拆分成多个简单的常量定义。
因式分解的常量定义中,如果某一行没有赋值,则默认和上一行一致。
package main
import "fmt"
func main() {
// 常量因式分解
const (
v1 = 123
v2 = 456
pi = 9.9
v3
)
fmt.Println(v1, v2, pi, v3)
}
/*
123 456 9.9 9.9
*/
2、全局
全局常量的定义与局部常量类似,只是没有使用 :=
这个简短的声明方式。
package main
import "fmt"
// 全局常量
const pi = 3.1415926
const e = 2.7182
// const同时声明多个常量,如果省略了值则表示和上面一行的值相同
const (
n1 = 10
n2
n3
)
func main() {
// 定义常量
const age = 98
fmt.Println(pi, e, age) // 3.1415926 2.7182 98
fmt.Println(n1, n2, n3) // 10 10 10
}
3、iota
iota
是 golang 语言的常量计数器,只能在常量的表达式中使用。
iota
在 const
关键字出现时将被重置为 0,const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
可有可无,当做一个在声明常量时的一个计数器。
package main
func main() {
const (
monday = iota + 1
tuesday
wednesday
thursday
friday
saturday
sunday
)
const (
n1 = iota
n2
n3
)
fmt.Println(monday, tuesday, wednesday, thursday, friday, saturday, sunday)
fmt.Println(n1, n2, n3)
}
/*
1 2 3 4 5 6 7
0 1 2
*/
(1)可以使用 _
跳过某些值
package main
import "fmt"
func main() {
const (
n1 = iota
n2
_
n4
)
fmt.Println(n1, n2, n4) // 0 1 3
}
(2)插队
package main
import "fmt"
func main() {
const (
n1 = iota
n2 = 100
n3 = iota
n4
)
const n5 = iota
fmt.Println(n1, n2, n3, n4, n5) // 0 100 2 3 0
}
(3)定义数量级
package main
import "fmt"
const (
_ = iota
KB = 1 << (10 * iota) // 左移10位,1左移10位,即1乘以2的10次方
MB = 1 << (10 * iota) // 左移20位,1左移20位,即1乘以2的20次方
GB = 1 << (10 * iota)
TB = 1 << (10 * iota) // 左移40位,1左移40位,即1乘以2的40次方
PB = 1 << (10 * iota)
)
func main() {
fmt.Println(KB, MB, GB, TB, PB) // 1024 1048576 1073741824 1099511627776 1125899906842624
}
(4)多个 iota 定义在一行
package main
import "fmt"
const (
a, b = iota + 1, iota + 2 // iota = 0, a = 1, b = 2
c, d // iota = 1, c = 2, d = 3
e, f // iota = 2, e = 3, f = 4
)
func main() {
fmt.Println(a, b, c, d, e, f) // 1 2 2 3 3 4
}
4、练习或示例
练习1:定义两个常量Male=1和Female=2,获取当前时间的秒数,如果能被Female整除则打印“女”,否则打印“男”。
package main
import (
"fmt"
"time"
)
// 定义两个常量Male=1和Female=2,获取当前时间的秒数,如果能被Female整除则打印“女”,否则打印“男”
const (
Male = 1
Female = 2
)
func main() {
Second := time.Now().Unix() // 获取当前时间的秒数
fmt.Println(Second)
if Second%Female == 0 {
fmt.Println("女")
} else {
fmt.Println("男")
}
}
/*
1683208344
女
*/
五、输入
让用户输入数据,完成项目交互。
- fmt.Scan
- fmt.Scanln
- fmt.Scanf
package main
import "fmt"
func main() {
// 示例1:fmt.Scan
/*
var name string
fmt.Println("请输入用户名:")
fmt.Scan(&name)
fmt.Printf(name)
*/
// 示例2:fmt.Scan
var name string
var age int
fmt.Println("请输入用户名:")
// 当使用Scan时,会提示用户输入
// 用户输入完成之后,会得到两个值:count,用户输入了几个值;err,用输入错误则是错误信息
_, err := fmt.Scan(&name, &age)
if err == nil {
fmt.Println(name, age)
} else {
fmt.Println("用户输入数据错误", err)
}
// 特别说明:fmt.Scan 要求输入两个值,必须输入两个,否则他会一直等待。
}
package main
import "fmt"
func main() {
// 示例1:fmt.Scanln
/*
var name string
fmt.Print("请输入用户名:")
fmt.Scanln(&name)
fmt.Printf(name)
*/
// 示例2:fmt.Scanln
var name string
var age int
fmt.Print("请输入用户名:")
// 当使用Scanln时,会提示用户输入
// 用户输入完成之后,会得到两个值:count,用户输入了几个值;err,用输入错误则是错误信息
count, err := fmt.Scanln(&name, &age)
fmt.Println(count, err)
fmt.Println(name, age)
// 特别说明:fmt.Scanln 等待回车。
}
package main
import "fmt"
func main() {
var name string
var age int
fmt.Print("请输入用户名:")
_, _ = fmt.Scanf("我叫%s 今年%d 岁", &name, &age)
fmt.Println(name, age)
}
无法解决的难题?
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// line,从stdin中读取一行的数据(字节集合 -> 转化成为字符串)
// reader默认一次能4096个字节(4096/3)
// 1. 一次性读完,isPrefix=false
// 2. 先读一部分,isPrefix=true,再去读取isPrefix=false
line, _, _ := reader.ReadLine()
data := string(line)
fmt.Println(data)
}
标签:语句,golang,name,package,fmt,运算符,var,Println,main
From: https://www.cnblogs.com/xiugeng/p/17375637.html