Go(一):Go基础语法入门

Go基础语法入门

    • 第一个go程序
    • 变量
    • 常量
    • 数据类型
    • 字符串处理
    • `++` `--` 运算符
    • 逻辑运算符
    • 循环 `for ... := range ...`
    • `switch`
    • 死循环
    • 数组的CURD
    • `map`的CURD
    • 函数
    • `defer`
    • `init`初始化函数
    • 指针
    • `类型定义` 与 `类型别名`
    • 结构体
    • 方法
    • 接口
    • 继承
    • 构造函数

第一个go程序

  • go.mod
    module go-app
    
    go 1.20
    
  • user/user.go
    package user
    
    // Hello 首字母大写为公共方法
    func Hello() string {
        return "Hello"
    }
    
  • main.go
    package main
    
    import (
        "fmt"
        "go-app/user"
    )
    
    func main() {
        str := user.Hello()
        fmt.Println(str)
    }
    

变量

声明的变量必须使用,否则报错异常

package main

import (
	"fmt"
)

func funA() (string, int) {
	// 匿名变量
	return "Lee", 12
}

func main() {
	// 变量初始化
	var name string = "123"
	fmt.Println(name) // 123

	// 批量变量初始化
	var (
		realName string = "Lee"
		age      int    = 24
		sex      string = "难~"
	)
	fmt.Printf("%v ---> %v ---> %v \n", realName, age, sex) // Lee ---> 24 ---> 难~

	// 类型推断
	var say = "Hello"
	fmt.Println(say) // Hello

	// 批量初始化
	var a, b, c = 1, 2, 3
	fmt.Printf("%v ---> %v ---> %v \n", a, b, c) // 1 ---> 2 ---> 3

	// (短变量声明)只能应用于函数内部
	x := 4
	y := 5
	z := 6
	fmt.Printf("%v ---> %v ---> %v \n", x, y, z) // 4 ---> 5 ---> 6

	// 匿名变量
	str, num := funA()
	fmt.Println(str, num) // Lee 12
}

常量

  • 基本常量
    const HELLO = "Hello Lee!!!"
    
  • iota 从0开始,每次调用自动加1
    const (
        count1 = iota
        count2 = iota
        count3 = iota
    )
    fmt.Println(count1, count2, count3) // 0 1 2
    
  • _ 跳过
    const (
        count1 = iota
        _
        count3 = iota
    )
    fmt.Println(count1, count3) // 0 2
    
  • 中间插值 等价于跳过
    const (
        count1 = iota
        count2 = 100
        count3 = iota
    )
    fmt.Println(count1, count2, count3) // 0 100 2
    

数据类型

package main

import "fmt"

func i() string {
	return "I"
}

func main() {
	var a = "Lee"
	var b = 18
	var c = true // 注意:不允许用0或1来表示false或true
	var d = 12.5
	var e = &d                                                                                                    // 取d的地址(指针类型)
	var f = [...]int{1, 2, 3}                                                                                     // [...] 省略长度
	var g = []int{1, 2, 3}                                                                                        // 动态数组
	var h = [4]int{1, 2, 3}                                                                                       // 固定长度数组
	var j = `
		
			
				Hello Lee
			
		
		` // 字符串字面量,可换行

	fmt.Printf("%T \n", a)   // string
	fmt.Printf("%T \n", b)   // int
	fmt.Printf("%T \n", c)   // bool
	fmt.Printf("%T \n", d)   // float64
	fmt.Printf("%T \n", e)   // *float64
	fmt.Printf("%T \n", f)   // [3]int
	fmt.Printf("%T \n", g)   // []int
	fmt.Printf("%T \n", h)   // [4]int
	fmt.Printf("%T \n", i)   // func() string
	fmt.Printf("%T \n", nil) // 
	fmt.Printf("%v \n", j)   // 字符串...

}

字符串处理

package main

import (
	"bytes"
	"fmt"
	"strings"
)

func main() {

	// 字符串拼接
	a := "Hello"
	b := "Lee"
	msg1 := fmt.Sprintf("%s %s!!!", a, b)
	fmt.Println(msg1) // Hello Lee!!!

	msg2 := strings.Join([]string{a, b}, "-")
	fmt.Println(msg2) // Hello-Lee

	var buffer bytes.Buffer
	buffer.WriteString("Hello ")
	buffer.WriteString("Lee")
	fmt.Println(buffer.String()) // Hello Lee

	// 字符串切片
	msg3 := "Hello Lee, My name is WangDeFa!!!"
	fmt.Println(msg3[1])   // 101 获取字符串索引为1的原始字节
	fmt.Println(msg3[2:7]) // llo L
	fmt.Println(msg3[3:])  // lo Lee, My name is WangDeFa!!!
	fmt.Println(msg3[:4])  // Hell

	// 字符串分割
	msg4 := "Hello Lee, My name is WangDeFa!!!"
	fmt.Println(strings.Split(msg4, "e")) // [H llo L  , My nam  is WangD Fa!!!]

	// 是否包含某个字符串
	msg5 := "Hello Lee!!!"
	fmt.Println(strings.Contains(msg5, "ee"))  // true
	fmt.Println(strings.Contains(msg5, "ele")) // false

	// 转换为大小写
	msg6 := "Hello Lee!!!"
	fmt.Println(strings.ToUpper(msg6)) // HELLO LEE!!!
	fmt.Println(strings.ToLower(msg6)) // hello lee!!!

	// 判断开头或结尾是否有指定字符串
	msg7 := "Hello Lee!!!"
	fmt.Println(strings.HasPrefix(msg7, "Hello"))  // true
	fmt.Println(strings.HasSuffix(msg7, "Lee"))    // false
	fmt.Println(strings.HasSuffix(msg7, "Lee!!!")) // true

	// 查询字符串索引值
	msg8 := "Hello Lee!!!"
	fmt.Println(strings.Index(msg8, "ee")) // 7
	fmt.Println(strings.Index(msg8, "e"))  // 1
}

++ -- 运算符

++ -- 是单独的运算符,不能添加到表达式中

package main

import "fmt"

func main() {
	a := 123

	a++
	fmt.Println(a) // 124

	a--
	fmt.Println(a) // 123
}

错误形式

a := 123
++a // Error: '++' unexpected
--a // Error: '--' unexpected
123 + a++ // Error: Cannot assign to 123 +

逻辑运算符

|| && ! 只能应用于bool值之间

循环 for ... := range ...

package main

import "fmt"

func main() {
	list := [...]any{"Lee", 25, "☹️"}
	for i, d := range list {
		fmt.Println(i, d) // 0 Lee   1 25   2 ☹️
	}
}

switch

和其他语言不同,不需要添加break

package main

import "fmt"

func main() {
	var num int
	fmt.Scan(&num)
	switch num {
	case 1:
		fmt.Println(num)
	case 2:
		fmt.Println(num)
	case 3:
		fmt.Println(num)
	case 4, 5, 6:
		fmt.Println(num)
	default:
		fmt.Println("空")
	}
}

case表达式

package main

import "fmt"

func main() {
	var score int
	fmt.Scan(&score)
	switch {
	case score >= 90 && score <= 120:
		fmt.Println("优秀")
	case score > 120:
		fmt.Println("作弊")
	default:
		fmt.Println("一般")
	}
}

实现类似其他语言不添加break的效果(fallthrough)

package main

import "fmt"

func main() {
	var num int
	fmt.Scan(&num) // 1 --> 一 二 三   2 --> 二 三
	switch num {
	case 1:
		fmt.Println("一")
		fallthrough
	case 2:
		fmt.Println("二")
		fallthrough
	case 3:
		fmt.Println("三")
	case 4, 5, 6:
		fmt.Println("四五六")
	default:
		fmt.Println("空")
	}
}

死循环

package main

import "fmt"

func main() {
	count := 0
	for {
		count++
		fmt.Println(count) // ...
	}
}

跳出循环

package main

import "fmt"

func main() {
	count := 0
	for {
		count++
		fmt.Println(count) // 1 - 100
		if count > 99 {
			break
		}
	}
}
package main

import "fmt"

func main() {
	count := 0
	for {
		count++
		fmt.Println(count) // 1 - 11
		if count > 10 {
			goto endPrint
		}
	}

endPrint: // 标签
	fmt.Println("结束")
}

数组的CURD

package main

import "fmt"

func main() {
	list := []any{1, true, "Lee"}

	// 增
	res1 := append(list, "啥?")
	fmt.Println(list) // [1 true Lee]
	fmt.Println(res1) // [1 true Lee 啥?]
	res2 := append(list, res1...)
	fmt.Println(list) // [1 true Lee]
	fmt.Println(res2) // [1 true Lee 1 true Lee 啥?]

	// 改
	list[1] = "假"
	fmt.Println(list) // [1 假 Lee]

	// 查
	fmt.Println(list[2])  // Lee
	fmt.Println(list[1:]) // [假 Lee]

	// 浅拷贝
	res3 := list
	res3[0] = 123
	fmt.Println(list) // [123 假 Lee]
	fmt.Println(res3) // [123 假 Lee]

	// 深克隆
	res4 := make([]any, len(list))
	copy(res4, list)
	res4[1] = 456
	fmt.Println(list) // [123 假 Lee]
	fmt.Println(res4) // [123 456 Lee]

	// 删 - 删除索引1
	list = append(list[:1], list[2])
	fmt.Println(list) // [123 Lee]
}

map的CURD

CURD

package main

import "fmt"

func main() {
	//data := make(map[string]any)
	//data["name"] = "Lee"
	data := map[string]any{
		"name": "Lee",
	}
	// 改
	data["name"] = "Tom"
	// 增
	data["age"] = 18
	data["height"] = 171
	// 删
	delete(data, "height")
	// 查
	fmt.Printf("%v ---> %v ---> %v", data["name"], data["age"], data["height"]) // Tom ---> 18 ---> 
}

拷贝

package main

import "fmt"

func main() {
	data1 := map[string]any{
		"name":   "Lee",
		"age":    18,
		"height": 171,
	}

	// 浅拷贝
	data2 := data1
	data2["name"] = "Tom"
	fmt.Printf("%v ---> %v ---> %v\n", data1["name"], data1["age"], data1["height"]) // Tom ---> 18 ---> 171
	fmt.Printf("%v ---> %v ---> %v\n", data2["name"], data2["age"], data2["height"]) // Tom ---> 18 ---> 171

	// 深克隆
	data3 := make(map[string]any)
	for key, value := range data1 {
		data3[key] = value
	}
	data3["name"] = "Lucy"
	fmt.Printf("%v ---> %v ---> %v\n", data1["name"], data1["age"], data1["height"]) // Tom ---> 18 ---> 171
	fmt.Printf("%v ---> %v ---> %v\n", data3["name"], data3["age"], data3["height"]) // Lucy ---> 18 ---> 171

}

判断字段是否存在

package main

import "fmt"

func main() {
	data := map[string]any{
		"name":   "Lee",
		"age":    18,
		"height": 171,
	}

	height, hasHeight := data["height"]
	fmt.Println(height, hasHeight) // 171 true

	like, hasLike := data["like"]
	fmt.Println(like, hasLike) //  false
}

函数

基本函数

package main

import "fmt"

func sum1(a int, b int) (res int) {
	res = a + b
	return res
}

func sum2(a int, b int) int {
	res := a + b
	return res
}

func sum3(a int, b int) (int, int, int) {
	res := a + b
	return a, b, res
}

func sum4(a int, b int, c ...int) int {
	res := a + b
	for _, v := range c {
		res += v
	}
	return res
}

func main() {
	fmt.Println(sum1(1, 1)) // 2

	fmt.Println(sum2(1, 1)) // 2

	fmt.Println(sum3(1, 1)) // 1 1 2

	a, b, c := sum3(1, 1)
	fmt.Println(a, b, c) // 1 1 2

	fmt.Println(sum4(1, 2, 3, 4, 5)) // 15
}

函数类型

package main

import "fmt"

type demo func(int, int) int

func sum(a int, b int) int {
	return a + b
}

func max(a int, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func main() {
	var d demo

	d = sum
	s := d(1, 2)
	fmt.Println(s) // 3

	d = max
	m := d(1, 2)
	fmt.Println(m) // 2
}

回调函数

package main

import "fmt"

func sayHello(name string, callback func(string)) {
	fmt.Printf("%v: Hello!\n", name)
	name = "Tom"
	if callback != nil {
		callback(name)
	}
}

func sayHi(name string) {
	fmt.Printf("%v: Hi!\n", name)
}

func main() {
	sayHello("Lee", sayHi) // Lee: Hello!   Tom: Hi!
}

匿名函数

package main

import "fmt"

func sayHello(name string, callback func(string)) {
	fmt.Printf("%v: Hello!\n", name)
	name = "Tom"
	if callback != nil {
		callback(name)
	}
}

func main() {
	sayHello("Lee", func(name string) {
		fmt.Printf("%v: Hi!\n", name)
	}) // Lee: Hello!   Tom: Hi!
}

立即执行函数

package main

import "fmt"

func main() {
	name := func(name string) string {
		return name
	}("Lee")

	fmt.Println(name) // Lee
}

闭包

package main

import "fmt"

func say() func(string) string {
	msg := "Hi, "
	return func(s string) string {
		msg += s
		return msg
	}
}

func main() {
	str := say()
	fmt.Println(str("Lee"))   // Hi, Lee
	fmt.Println(str("-Tom.")) // Hi, Lee-Tom.
}

递归

package main

import "fmt"

func fun(n int) int {
	if n == 0 {
		return 1
	}
	return n * fun(n-1)
}

func main() {
	fmt.Println(fun(3)) // 6
}

defer

先定义的后输出

package main

import "fmt"

func main() {
	fmt.Println(1)
	fmt.Println(2)
	fmt.Println(3)
	defer fmt.Println(4)
	defer fmt.Println(5)
	defer fmt.Println(6)
	defer fmt.Println(7)
	fmt.Println(8)
	fmt.Println(9)
	fmt.Println(0)

	// 结果:123 890 7654
}

init初始化函数

执行顺序 变量函数 ---> init函数(按从上到下) ---> main函数

package main

import "fmt"

func init() {
	fmt.Println("init1")
}

var data = func() any {
	fmt.Println("num")
	return nil
}()

func init() {
	fmt.Println("init2")
}

func main() {
	fmt.Println("main")
}

func init() {
	fmt.Println("init3")
}

// 结果: num init1 init2 init3 main

指针

package main

import "fmt"

func main() {
	var a = 123
	var b *int // int类型的指针变量

	// 打印变量值
	fmt.Println(b) // 

	// 打印变量地址
	fmt.Println(&a) // 0xc0000ac008
	fmt.Println(&b) // 0xc0000a6018

	b = &a
	// 打印变量地址
	fmt.Println(b) // 0xc0000ac008
	// 打印变量值
	fmt.Println(*b) // 123
}

指向数组的指针

package main

import "fmt"

func main() {
	var a = []int{1, 2, 3}
	var b [3]*int

	// 打印变量值
	fmt.Println(b) // [  ]

	// 打印变量地址
	fmt.Println(&a)                  // &[1 2 3]
	fmt.Println(&a[0], &a[1], &a[2]) // 0xc00001e0d8 0xc00001e0e0 0xc00001e0e8
	fmt.Println(&b)                  // &[  ]
	fmt.Println(&b[0], &b[1], &b[2]) // 0xc000010048 0xc000010050 0xc000010058

	for i := range a {
		b[i] = &a[i]
		fmt.Println(b[i])  // 0xc00001e0d8 0xc00001e0e0 0xc00001e0e8
		fmt.Println(*b[i]) // 1 2 3
	}
}

类型定义类型别名

package main

import "fmt"

// NewInt 自定义类型
type NewInt int

// NewBool 类型别名
type NewBool = bool

func main() {
	var a NewInt
	fmt.Println(a) // 0
	var b NewBool
	fmt.Println(b) // false
}

结构体

package main

import "fmt"

type UserInfo struct {
	name   string
	age    int
	height float64
}

func main() {
	var info UserInfo
	info.name = "Lee"
	info.age = 18
	info.height = 171
	fmt.Println(info) // {Lee 18 171}
}

匿名结构体

package main

import "fmt"

func main() {
	var info struct {
		name   string
		age    int
		height float64
	}
	info.name = "Lee"
	info.age = 18
	info.height = 171
	fmt.Println(info) // {Lee 18 171}
}

结构体赋值

package main

import "fmt"

type UserInfo struct {
	name        string
	age, height int
}

func main() {
	
	var info UserInfo

	// 方式1
	info.name = "Lee"
	info.age = 18
	info.height = 171

	// 方式2
	info = UserInfo{
		"Lee", 18, 171,
	}

	// 方式3
	info = UserInfo{
		name:   "Lee",
		height: 171,
	}

	fmt.Println(info) // {Lee 18 171}
}

结构体的指针

package main

import "fmt"

type UserInfo struct {
	name        string
	age, height int
}

func main() {
	var lee *UserInfo

	fmt.Println(lee)  // 
	fmt.Println(&lee) // 0xc000012028

	var tom = UserInfo{
		name:   "Lee",
		age:    18,
		height: 171,
	}

	lee = &tom
	fmt.Println(lee)  // &{Lee 18 171}
	fmt.Println(&lee) // 0xc000012028
	fmt.Println(*lee) // {Lee 18 171}
}
package main

import "fmt"

type UserInfo struct {
	name        string
	age, height int
}

func main() {
	// 初始化结构体的指针
	var lee = new(UserInfo)

	fmt.Println(lee)  // &{ 0 0}
	fmt.Println(&lee) // 0xc000012028

	var tom = UserInfo{
		name:   "Lee",
		age:    18,
		height: 171,
	}

	lee = &tom
	fmt.Println(lee)  // &{Lee 18 171}
	fmt.Println(&lee) // 0xc000012028
	fmt.Println(*lee) // {Lee 18 171}
}

结构体的嵌套

package main

import "fmt"

type UserInfo struct {
	name        string
	age, height int
}

type Person struct {
	userInfo UserInfo
	msg      string
}

func main() {
	var tom = Person{
		userInfo: UserInfo{
			name:   "Lee",
			age:    18,
			height: 171,
		},
		msg: "Hi",
	}
	fmt.Println(tom) // {{Lee 18 171} Hi}
}

结构体作为参数

package main

import "fmt"

type UserInfo struct {
  name        string
  age, height int
}

type Person struct {
  userInfo UserInfo
  msg      string
}

func say1(person Person) {
  person.msg = "Hello"
  person.userInfo.name = "Tom"
  fmt.Println(person.msg, person.userInfo.name)
}

func say2(person *Person) {
  person.msg = "Hello"
  person.userInfo.name = "Tom"
  fmt.Println(person.msg, person.userInfo.name)
}

func main() {
  var person1 = Person{
    userInfo: UserInfo{
      name:   "Lee",
      age:    18,
      height: 171,
    },
    msg: "Hi",
  }
  say1(person1)                      // Hello Tom
  fmt.Println(person1.msg)           // Hi
  fmt.Println(person1.userInfo.name) // Lee

  var person2 = Person{
    userInfo: UserInfo{
      name:   "Lee",
      age:    18,
      height: 171,
    },
    msg: "Hi",
  }
  say2(&person2)                     // Hello Tom
  fmt.Println(person2.msg)           // Hello
  fmt.Println(person2.userInfo.name) // Tom
}

方法

方法的接收者是结构体,包含值类型和引用类型时,那么值类型被复制,引用类型不被复制而是引用

package main

import "fmt"

type UserInfo struct {
  name        string
  age, height int
  likes       []string
}

// info为接收者用于接收
func (info UserInfo) say() {
  info.age = 20
  info.likes[2] = "play"
  fmt.Println(info)
}

func main() {
  var userInfo = UserInfo{
    name:   "Lee",
    age:    18,
    height: 171,
    likes:  []string{"吃", "喝", "玩", "乐"},
  }
  userInfo.say()        // {Lee 20 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
  fmt.Println(userInfo) // {Lee 18 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
}

方法的接收者是指针类型结构体时,那么不被复制而是引用

package main

import "fmt"

type UserInfo struct {
	name        string
	age, height int
	likes       []string
}

// info为接收者用于接收
func (info *UserInfo) say() {
	info.age = 20
	info.likes[2] = "play"
	fmt.Println(*info)
}

func main() {
	var userInfo = UserInfo{
		name:   "Lee",
		age:    18,
		height: 171,
		likes:  []string{"吃", "喝", "玩", "乐"},
	}
	userInfo.say()        // {Lee 20 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
	fmt.Println(userInfo) // {Lee 20 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
}

接口

接口内的方法必须定义,否则报错

package main

import "fmt"

// Sayer 说接口
type Sayer interface {
	say(msg string)
}

// Mover 移动接口
type Mover interface {
	move(start int, end int) (name string, distance int)
}

// Animaler 动物接口
type Animaler interface {
	Sayer
	Mover
}

// Lee 结构体,存放姓名
type Lee struct {
	name string
}

func (lee Lee) say(msg string) {
	fmt.Println(msg + lee.name)
}

func (lee Lee) move(start int, end int) (name string, distance int) {
	distance = end - start
	return lee.name, distance
}

func main() {
    var lee Animaler
    lee = Lee{name: "Lee"}
	lee.say("Hi,")
	name, distance := lee.move(0, 10)
	fmt.Println(name, distance)
}

OCP: “开-闭”原则

package main

import "fmt"

type Animaler interface {
	eat()
	sleep()
}

type Person struct {
	name string
}

func (person Person) eat() {
	fmt.Println(person.name + ",吃...")
}

func (person Person) sleep() {
	fmt.Println(person.name + ",睡...")
}

func funA(animal Animaler) {
	animal.eat()
	animal.sleep()
}

func (person Person) funB(animal Animaler) {
	animal.eat()
	animal.sleep()
}

func main() {
	var animal Animaler = Person{name: "Dog"}
	animal.eat()   // Dog,吃...
	animal.sleep() // Dog,睡...
	funA(animal)   // Dog,吃...  Dog,睡...

	var lee Animaler = Person{name: "Lee"}
	var tom Animaler = Person{name: "Tom"}
	person := Person{}
	person.funB(lee) // Lee,吃...  Lee,睡...
	person.funB(tom) // Tom,吃...  Tom,睡...
}

继承

结构体嵌套来实现继承

继承自UserUserInfo结构体

package main

import "fmt"

// User 父结构体
type User struct {
  say   func(msg string)
  sleep func()
}

// UserInfo 子结构体
type UserInfo struct {
  name   string
  age    int
  height float64
  User
}

func main() {
  lee := UserInfo{
    name:   "Lee",
    age:    18,
    height: 171.123,
    User: User{
      say: func(msg string) {
        fmt.Println(msg)
      },
      sleep: func() {
        fmt.Println("sleep...")
      },
    },
  }

  fmt.Println(lee) // {Lee 18 171.123 {0x102f8f610 0x102f8f690}}

  lee.say("Hi," + lee.name)      // Hi,Lee
  lee.User.say("Hi," + lee.name) // Hi,Lee

  lee.User.sleep() // sleep...
  lee.sleep()      // sleep...
}

构造函数

package main

import "fmt"

type UserInfo struct {
	name   string
	age    int
	height float64
}

// initUserInfo 构造函数
func initUserInfo(name string, age int, height float64) *UserInfo {
	return &UserInfo{name: name, age: age, height: height}
}

func main() {

	info := UserInfo{
		name:   "Lee",
		age:    18,
		height: 171.123,
	}

	person := initUserInfo(info.name, info.age, info.height)
	fmt.Println(info)   // {Lee 18 171.123}
	fmt.Println(person) // &{Lee 18 171.123}

	person.name = "Tom"
	fmt.Println(info)   // {Lee 18 171.123}
	fmt.Println(person) // &{Tom 18 171.123}
}

你可能感兴趣的:(Go,golang,开发语言,go)