go语言语法学习随笔| 豆包MarsCode AI刷题

86 阅读6分钟

:=与=的区别

在Go语言中,:== 都是用于赋值的操作符,但它们之间有一些区别:

  1. := 用于声明并初始化变量

    • 当你在函数内部使用 := 时,它会自动推断变量的类型,并声明一个新的变量。

    • 这个操作符只能在函数内部使用,不能在全局作用域中使用。

    • 例如:

      func main() {
      ​
        x := 10
      ​
        fmt.Println(x) // 输出: 10
      ​
      }
      
  2. = 用于赋值操作

    • 当你已经声明了一个变量,你可以使用 = 来给这个变量赋值。

    • 这个操作符可以在函数内部和全局作用域中使用。

    • 例如:

      var y int
      ​
      y = 20
      ​
      fmt.Println(y) // 输出: 20
      

总结来说,:= 是用于声明并初始化变量的操作符,而 = 是用于给已经声明的变量赋值的操作符。在函数内部,如果你需要声明一个新的变量并同时给它赋值,你应该使用 :=。如果你已经声明了变量,只是需要给它赋一个新的值,你应该使用 =

strconv包的简单使用方式

在Go语言中,strconv.ParseInt 函数用于将字符串转换为指定进制的整数。该函数返回两个值:转换后的整数值和可能发生的错误。

在你的代码中,strconv.ParseInt(t.Hour()) 尝试将当前时间的小时数(t.Hour() 返回的是一个 int 类型的值)转换为整数。然而,ParseInt 函数需要一个字符串作为输入参数,而不是一个整数。因此,这里出现了类型不匹配的问题,导致了编译错误。

错误信息 multiple-value strconv.ParseInt(t.Hour()) (value of type (i int64, err error)) in single-value context 指出了这个问题:ParseInt 函数返回了两个值(ierr),但你只尝试接收了一个值。

为了解决这个问题,你需要确保提供给 ParseInt 函数的参数是一个字符串,并且正确地处理函数返回的两个值。

t := time.Now()
hourStr := strconv.Itoa(t.Hour())
hourInr, err := strconv.ParseInt(hourStr, 10, 64)
if err != nil {
    fmt.Println("Error parsing hour:", err)
} else {
    switch {
    case t.Hour() < 12:
        fmt.Println("It's before noon", hourInr)
    default:
        fmt.Println("It's after noon", hourInr)
    }
}

strconv.Itoa函数与strconv.ParseInt函数效果为逆过程

go语言的终端输出

go语言输出可以说是无视输出变量的类型,在fmt.Println中类似于C语言的输出格式将每一个变量只需要简单的用逗号隔开就能在一行一并输出。而且对于数组的输出也可以直接在函数内使用数组变量名将数组全部输出。

例如:

var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
    twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)

go语言在数组后面的追加操作

func append(slice []Type, elems ...Type) []Type函数在追加过程中会重新创建一个新的数组,并且数组的大小为原数组大小与添加数据量之和。

举个栗子:

代码一:
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])   // c
fmt.Println("len:", len(s)) // 3
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s) // [a b c d e f]
输出一:
get: c
len: 3
[a b c d e f]

当不将s[2]赋值则结果如下:

代码二:
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
fmt.Println("get:", s[2])   // c
fmt.Println("len:", len(s)) // 3
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s) // [a b c d e f]
输出二:
get: 
len: 3
[a b  d e f]

go语言中奇怪的map形式

go语言中将map的键值对改为与数组类似的形式。在map中的Key为map中的"下标",value为map特定"下标"Key对应的值。

举个例子:

//声明一个字符串到整型的map
m := make(map[string]int)
//初始化map
m["one"] = 1
m["two"] = 2
// 声明并初始化一个字符串到整型的map
map2 := map[string]int {
    "one": 1,
    "two": 2,
}
//打印全部键值对
fmt.Println(m)           // map[one:1 two:2]
//打印map集合的大小
fmt.Println(len(m))      // 2
//打印对应键值
fmt.Println(m["one"])    // 1
fmt.Println(m["unknow"]) // 0
//通过键查询map
r, ok := m["unknow"]
fmt.Println(r, ok) // 0 false(查询成功输出:value true)

震惊:go语言中疑似定义函数过程中将函数返回值变量名确定

go语言的函数定义形式简直太花哨了,各种各样的形式,有确定变量名字的也有确定变量类型的

func add(a int, b int) int {
    return a + b
}
​
func add2(a, b int) int {
    return a + b
}
​
func values() (int, int) {
    return 3, 7
}
​
func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}
​
func exists(m map[string]string, k string) (v string, ok bool) {
    v, ok = m[k]
    // return v, ok(不需要,完全不需要)
    return
}
​
func main() {
    res := add(1, 2)
    fmt.Println(res) // 3
​
    v, ok := exists(map[string]string{"a": "A"}, "a")
    fmt.Println(v, ok) // A True
​
    a, b := values()
    fmt.Println(a, b)//3 7
​
    a, b = split(10)
    fmt.Println(a, b)//4 6
}

对于一个结构体内部的函数有如下两种表现方式

type user struct {
    a     string
    b     string
}
​
//不是指针的情况下不可以修改结构体内部的值
func (u user) checkPassword(b string) bool {
    return u.b == b
}
​
//为结构体的指针可以修改结构体内部的值
func (u *user) resetPassword(password string) {
    u.b = b
}
​
func main() {
    a := user{a: "wang", b: "1024"}
    a.resetPassword("2048")
    fmt.Println(a.checkPassword("2048")) // true
}

Strings包的常见方法

strings.Contains(s, substr string) bool:输出bool判断是否存在substr子串

strings.Count(s, substr string) int:输出int查询存在substr子串的出现次数

strings.HasPrefix(s, prefix string) bool:输出bool判断是否以prefix开头

strings.HasSuffix(s, suffix string) bool:输出bool判断是否以suffix结尾

strings.Index(s, substr string) int:输出int第一次出现substr子串的开头下标

strings.Join(elems []string, sep string) string:使用sepelems连接到一起生成一个新的字符串

strings.Repeat(s string, count int) string:输出一个字符串,并取值为将s重复count

strings.Replace(s, old, new string, n int) string:用于在字符串中old替换为new。它可以指定替换的次数n,如果n为 -1,则表示替换所有匹配的子串。

strings.Split(s, sep string) []string:用于将一个字符串分割成多个子串,并返回一个字符串切片。它接受两个参数:要分割的字符串 s 和分隔符 sep。如果 sep 为空字符串,则将 s 分割成每个字符的子串。如果 sep 未找到,则返回包含原始字符串的单个元素切片。

strings.ToLower(s string) string:将字符串中字母全部小写

strings.ToUpper(s string) string:将字符串中字母全部大写

GOPATHGo VendorGo Module

GOPATH:无法实现多版本控制,即一个电脑无法同时运行一个依赖新版本一个依赖老版本的两个项目

Go Vendor

  • 优点:会在vendor目录下创建package的副本在这里面就可以有效的实现多版本控制,如果vendor目录下没有则退回到GOPATH目录寻找package
  • 缺点:无法控制依赖的版本;更新项目又可能出现依赖冲突,导致编译出错。

Go Module

  • 通过go.mod文件管理依赖包版本
  • 通过go get/go mod指令工具管理依赖包
  • 配置文件,描述依赖:go.mod;中心仓库管理依赖库:Proxy;本地工具:go get/go mod