Go语言的基础语法分三个方面:变量、数据类型、控制结构
1、变量声明
- 1.1 标准声明 (var 变量名 变量类型)
//显示指定数据类型
var name string = `Coding君`
var age int
//只声明不立即初始化
var title string
//批量声明变量
var (
hobby string
score int
online bool
)
- 1.2 短变量声明 (:=)
//自动推断为string类型
name := `Coding君`
//自动推断为int类型
age := 18
//多返回值
val,err := getOne()
2、基本数据类型基本数据类型分为布尔型、数值型(整型|浮点型|复数型)、字符串型和派生类型(数组|切片|映射|结构体|指针)
//布尔型
var online bool
//数值型
//整型
var age int
var age int8
var age uint //无符号整型
//浮点型
var score float32
var score float64
//复数型
var complx complex64
var complx complex128
//字符串型
var name string
//派生类型 数组、切片、映射、结构体、指针
//数组
var hobbies [3]string //长度固定
hobbies[0] = "reading"
hobbies[1] = "coding"
hobbies[2] = "gaming"
fmt.Println("My hobbies are:", hobbies)
//切片,这是用的最多的
bodys := []string{} //长度不固定
bodys = append(bodys, "head", "shoulders", "knees", "toes")
fmt.Println("Body parts:", bodys)
//映射
bodyFunctions := map[string]string{}
bodyFunctions["head"] = "thinking"
bodyFunctions["shoulders"] = "carrying"
bodyFunctions["knees"] = "bending"
bodyFunctions["toes"] = "balancing"
fmt.Println("Body functions:", bodyFunctions)
//结构体 struct
type Person struct{
name string
age int
}
//指针
var xiaoming *Person
xiaoming = &Person{name: `小明`, age: 20}
fmt.Println("Name:", xiaoming.name, "Age:", xiaoming.age)
//推荐用法
xiaohong := &Person{name: `小红`, age: 18}
fmt.Println("Name:", xiaohong.name, "Age:", xiaohong.age)
打开go的源文件src/builtin/builtin.go查看类型的定义,如下:
package builtin
import "cmp"
// bool is the set of boolean values, true and false.
type bool bool
// true and false are the two untyped boolean values.
const (
true = 0 == 0 // Untyped bool.
false = 0 != 0 // Untyped bool.
)
// uint8 is the set of all unsigned 8-bit integers.
// Range: 0 through 255.
type uint8 uint8
// uint16 is the set of all unsigned 16-bit integers.
// Range: 0 through 65535.
type uint16 uint16
// uint32 is the set of all unsigned 32-bit integers.
// Range: 0 through 4294967295.
type uint32 uint32
// uint64 is the set of all unsigned 64-bit integers.
// Range: 0 through 18446744073709551615.
type uint64 uint64
// int8 is the set of all signed 8-bit integers.
// Range: -128 through 127.
type int8 int8
// int16 is the set of all signed 16-bit integers.
// Range: -32768 through 32767.
type int16 int16
// int32 is the set of all signed 32-bit integers.
// Range: -2147483648 through 2147483647.
type int32 int32
// int64 is the set of all signed 64-bit integers.
// Range: -9223372036854775808 through 9223372036854775807.
type int64 int64
// float32 is the set of all IEEE-754 32-bit floating-point numbers.
type float32 float32
// float64 is the set of all IEEE-754 64-bit floating-point numbers.
type float64 float64
// complex64 is the set of all complex numbers with float32 real and
// imaginary parts.
type complex64 complex64
// complex128 is the set of all complex numbers with float64 real and
// imaginary parts.
type complex128 complex128
// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string
// int is a signed integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, int32.
type int int
// uint is an unsigned integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, uint32.
type uint uint
// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr
// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8
// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32
// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}
// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }
// iota is a predeclared identifier representing the untyped integer ordinal
// number of the current const specification in a (usually parenthesized)
// const declaration. It is zero-indexed.
const iota = 0 // Untyped int.
// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
// Type is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int
// Type1 is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type1 int
// IntegerType is here for the purposes of documentation only. It is a stand-in
// for any integer type: int, uint, int8 etc.
type IntegerType int
// FloatType is here for the purposes of documentation only. It is a stand-in
// for either float type: float32 or float64.
type FloatType float32
// ComplexType is here for the purposes of documentation only. It is a
// stand-in for either complex type: complex64 or complex128.
type ComplexType complex64
关于类型的转换,Go要求显示转换,不支持隐式转换
var x int32 = 100
y := int64(x) // 必须显式转换
f := 3.14
i := int(f) // 浮点转整型会截断小数部分,i 的值为 3
fmt.Println("f:", f, "i:", i)
//打印结果:f: 3.14 i: 3
//但是,在实际中,我们使用cast包(github.com/spf13/cast)来转换数据
yy := cast.ToInt64(x)
fmt.Println("yy:", yy)
ii:= cast.ToInt(f)
fmt.Println("ii:", ii)
3、控制结构
- 3.1 条件语句(if/else)Go的if语句条件不需要小括号()包裹
// 常见的写法:在条件前初始化
if score := 85; score >= 90 { // 此处的 score 只在 if 和 else 块中有效
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
- 3.2 循环(for)Go中只有for一种循环关键字,没有while、do-white等其他循环
//标准循环
for i := 0; i < 5; i++ {
fmt.Println(i)
}
//类似 while 循环
for count:=0;count<10; {
fmt.Println("count:",count)
count++
}
//无限循环
for {
break // 立即退出循环
}
//遍历数组、切片、映射等集合类型时,使用 for range循环非常方便
//遍历数组
var arr = [3]string{"apple", "banana", "cherry"}
for index, fruit := range arr {
fmt.Printf("索引: %d, 水果: %s\n", index, fruit)
}
//遍历切片
for index, part := range bodys {
fmt.Printf("索引: %d, 部位: %s\n", index, part)
}
//遍历映射
for key, value := range bodyFunctions {
fmt.Printf("部位: %s, 功能: %s\n", key, value)
}
- 3.3 多路分支(switch)在 Go 中,每个
case默认会自动跳出,无需写break
weather := "晴天"
switch weather {
case "晴天":
fmt.Println("适合出去玩")
case "下雨":
fmt.Println("记得带伞")
case "下雪":
fmt.Println("注意保暖")
default:
fmt.Println("天气情况未知")
}
//把weather放在case里去判断
switch {
case weather == "晴天":
fmt.Println("适合出去玩")
case weather == "下雨":
fmt.Println("记得带伞")
case weather == "下雪":
fmt.Println("注意保暖")
default:
fmt.Println("天气情况未知")
}
//使用fallthrough实现穿透效果
//即无论匹配到哪个case,都会继续执行后续的case语句
//相当于去掉了默认的break
switch weather {
case "晴天":
fmt.Println("适合出去玩")
fallthrough
case "下雨":
fmt.Println("记得带伞")
fallthrough
case "下雪":
fmt.Println("注意保暖")
default:
fmt.Println("天气情况未知")
}
4、实践环节我们来做一个计算器吧
var num1, num2 float64
var operator string
// 获取用户输入
fmt.Print("请输入第一个数字: ")
_, err := fmt.Scanln(&num1)
if err != nil {
fmt.Println("输入错误,请输入数字")
return
}
fmt.Print("请输入第二个数字: ")
_, err = fmt.Scanln(&num2)
if err != nil {
fmt.Println("输入错误,请输入数字")
return
}
fmt.Print("请输入运算符 (+, -, *, /): ")
fmt.Scanln(&operator)
// 根据运算符进行计算
switch operator {
case "+":
fmt.Printf("%.2f + %.2f = %.2f\n", num1, num2, num1+num2)
case "-":
fmt.Printf("%.2f - %.2f = %.2f\n", num1, num2, num1-num2)
case "*":
fmt.Printf("%.2f * %.2f = %.2f\n", num1, num2, num1*num2)
case "/":
if num2 != 0 {
fmt.Printf("%.2f / %.2f = %.2f\n", num1, num2, num1/num2)
} else {
fmt.Println("错误:除数不能为零")
}
default:
fmt.Println("错误:未知的运算符")
}
//运行结果如下:
//请输入第一个数字: 1
//请输入第二个数字: 2
//请输入运算符 (+, -, *, /): +
//1.00 + 2.00 = 3.00
万丈高楼平地起,不积跬步无以至千里,坚持下去,终将美好