Go语言入门(二) | 青训营

151 阅读5分钟

Go语言函数

可以有多个返回值

基本语法

func 函数名(形参列表) (返回值类型列表){
        函数体
        return 返回值列表
}

两数相加示例

package main
import "fmt"

func add(num1 int,num2 int)(int){
    return num1+num2
}
//当只有一个返回值时 返回值()可省

func main() {
    a,b := 2,5
    fmt.Println(add(a,b)) //7
}

Go语言指针入门

场景 在函数内部改变变量的值

package main
import "fmt"

func add2(n int){
    n += 2
}

func main() {
    n := 5
    fmt.Println(add2(n)) // 5
}

此函数并不能对n进行+2操作 n的值不变

package main
import "fmt"

func add2ptr(n *int){
    *n +=2   //运算时+*
}

func main() {
    n := 5
    fmt.Println(add2ptr(&n)) // 7  调用时+&
}

结构体

定义结构体

type 结构体名 struct{
    变量名 变量类型
    变量名 变量类型
    ...
    }

package main

type stu struct{
    Name string
    Age int
}

func main(){
    // 创建对象
    // 方法一:先声明后赋值 
    var stu1 stu
    stu1.Name = "张三"
    stu.Age = 18
    
    // 方法二:声明时赋值
    var stu2 stu = stu{"李四",19}
    
    //方法三:返回结构体指针
    var stu3 *stu = new(stu)
    stu3.Name = "王五"
    stu3.Age = 31
    
    // 方法四:返回结构体指针
    var stu4 *stu = &stu{"赵六",9}
}

在方法中传入结构体参数可以选择传入指针和非指针 若传入指针 则可对结构体内容作修改

结构体方法

package main

type people struct{
    Name string
    Age int
}

// 传递非指针对象,不可更改对象属性
func (p people) checkAge(age int) bool {
    return p.Age == age
}

// 传递指针对象,可更改对象属性
func (p &people) resetName(name string) {
    p.Name = name
}

func main(){
    p1 := {"张三",57}
    p1.checkAge(32) //false
    p1.resetName("李四")
}

错误处理

首先导入errors,IDE有自动导入功能 可忽略

import "errors"

在函数返回值中加入一个error类型的返回值 err 返回时也需要返回两个值 简单用if语句判断是否出错 未出错 则error返回一个nil 否则可以New一个errors对象返回

package main
import (
    "errors"
    "fmt"
    )
func errs() (res int, err error){
    return 2,nil
}
func main(){
    res,err := errs()
    // 如果返回的错误不是空值,怎发生错误 打印处理
    // 这种方式在本次训练营多次用到
    if err != nil{
        fmt.Println(err)
        return
    }
}

字符串操作

package main

import (
	"fmt"
	"strings"
)

func main() {
    // 定义字符串
    a := "hello"
    
    // strings.Contains(str1,str2)                        str1是否包含str2
    fmt.Println(strings.Contains(a, "ll"))                // true
    
    // strings.Count(str1,str2)                           字符串str包含几个str2
    fmt.Println(strings.Count(a, "l"))                    // 2
    
    // strings.HasPrefix(str1,str2)                       字符串str1是否以str2开头
    fmt.Println(strings.HasPrefix(a, "he"))               // true
    
    // strings.HasSuffix(str1,str2)                       字符串str1是否以str2结尾
    fmt.Println(strings.HasSuffix(a, "llo"))              // true
    
    // strings.Index(str1,str2)                           字符串str1中第一次出现str2的下标位置 
    fmt.Println(strings.Index(a, "ll"))                   // 2
    
    // strings.Join([]string strs, char)                  用char疆字符串数组strs合并
    fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
    
    //strings.Repeat(str,num)                             将字符串str复制num遍并返回
    fmt.Println(strings.Repeat(a, 2))                     // hellohello
    
    //strings.Replace(str,old,new,n)                      用new将str中的old替换 n=-1表示替换所有 n非负表示替换前n个 
    fmt.Println(strings.Replace(a, "e", "E", -1))         // hEllo
    
    //strings.Split(str1,str2)                            用str2将str1切分 返回切分后的字符串数组
    fmt.Println(strings.Split("a-b-c", "-"))              // [a b c]
    
    // strings.ToLower(str)                               将str所有字母换成小写
    fmt.Println(strings.ToLower(a))                       // hello
    
    //strings.ToUpper(str)                                将str所有字母换成大写
    fmt.Println(strings.ToUpper(a))                       // HELLO
    
    // len(str)                                           返回字符串str查长度
    fmt.Println(len(a))                                   // 5
    
}

Print

package main
import "fmt"

func main(){
    // 换行打印
    fmt.Println("hello World")
    
    var everything
    // %v可为任意类型占位 无须区分数字和字符
    fmt.Printf("%v\n",everthing) 
    
    // %+v 可使得打印信息更详细
    
    // %#v 使打印信息最详细
    
    f := 3.1415926535
    // 保留两位小数
    fmt.Printf("%.2f",fn)
}

json 处理

在自定义结构体时 保证每个属性的首字母大写 即可使用 json.Marshal(对象名)将对象序列化 返回一个buf数组 需要string(buf)进行强转才能打印该字符串 var b usrInfo 还可以用json.Unmarshal(buf,&b)将buf反序列化

package main
import (
	"encoding/json"
	"fmt"
)

type userInfo struct {
	Name  string
	Age   int `json:"age"` //采用此方式可在打印时打印出小写或带下划线的样式
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
	buf, err := json.Marshal(a)
	if err != nil {
		panic(err)
	}
	fmt.Println(buf)         // [123 34 78 97...]
	fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}

	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))

	var b userInfo
	err = json.Unmarshal(buf, &b)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}

时间处理

t := time.Now() 返回当前时间对象

time.Date(y,m,d,h,m,s,0,time.UTC) 自定义时间

t.Year() t.Month() t.Day() t.Hour() t.Minute() t.Second() 分别返回年月日 时分秒

t1.Sub(t2) 返回一个时间段

package main
import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
        fmt.Println(now)                                           // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
	t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
	t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
	fmt.Println(t)                                                  // 2022-03-27 01:25:36 +0000 UTC
	fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
	fmt.Println(t.Format("2006-01-02 15:04:05"))                    // 2022-03-27 01:25:36
	diff := t2.Sub(t)
	fmt.Println(diff)                                               // 1h5m0s
	fmt.Println(diff.Minutes(), diff.Seconds())                     // 65 3900
	t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
	if err != nil {
		panic(err)
	}
	fmt.Println(t3 == t)                                            // true
	fmt.Println(now.Unix())                                         // 1648738080
}

字符串与数字间的转换

64表示64位

strconv.ParseFloat(str,64)

进制取0表示自动

strconb.ParseInt(str,进制,64)

可以设置Atoi自动进行字符与数字间的转换

strconv.Atoi(str)

进程

package main
import (
	"fmt"
	"os"
	"os/exec"
)

func main() {
	// go run example/20-env/main.go a b c d
	fmt.Println(os.Args)           // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
                                 // os.Args第一个返回值是一个临时目录 后面是执行的a b c d
	fmt.Println(os.Getenv("PATH")) //获取环境变量 /usr/local/go/bin...
	fmt.Println(os.Setenv("AA", "BB"))//写入环境变量
	buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf)) // 127.0.0.1       localhost
}