当前位置:网站首页>Golang学习笔记—基础篇

Golang学习笔记—基础篇

2022-06-11 19:25:00 Sentiment._

前言

这几天在复现之前比赛时发现go的出现频率越来越高了,所以借此也潜学一下go。个人学习笔记,由于有一丢丢的语言基础所以写的比较浅显。(写完这篇期末了 咕咕几天)

环境配置

开发环境

Downloads - The Go Programming Language (google.cn)

下载后选择路径安装即可

go verion查看版本

image-20220608174119106

Go Mod

Golang 无法下载依赖解决方案,需要翻墙才能下载。Go 1.11 版本开始,官方支持了 go module 包依赖管理工具。其实还新增了 GOPROXY
环境变量。如果设置了该变量,下载源代码时将会通过这个环境变量设置的代理地址,而不再是以前的直接从代码库下载。这无疑对我等无法科学上网的程序员来说是最大的福音。更可喜的是,https://goproxy.io/
这个开源项目帮我们实现好了我们想要的。该项目允许开发者一键构建自己的 GOPROXY 代理服务。同时,也提供了公用的代理服务
https://goproxy.io,我们只需设置该环境变量即可正常下载被墙的源码包了:

设置

set GO111MODULE=on
set GOPROXY=https://goproxy.io
go env   //运行结束后查看是否配置成功

开发工具

我用的是jetbrains的Goland,用VScode也可以

Download GoLand: A Go IDE with extended support for JavaScript, TypeScript, and databases (jetbrains.com)

设置GOROOT和GOPATH即可

image-20220608181202350

第一个程序

用Goland创建项目后会自动生成go.mod,如果不是通过项目创建的则可以通过命令创建go.mod文件

go mod init 文件夹名称

Hello, world!

package main

import "fmt"

func main() {
   fmt.Println("Hello, world!")
}

结果

image-20220608181256047

运行后控制台一直出现多余信息,将它折叠掉

Ctrl+Shift+V
输入Registry
将go.run.process.with.pty取消勾选即可

image-20220608181914041

变量

Go语言中的变量需要声明后才能使用,并且变量声明后必须使用

变量声明

语法

声明变量的一般形式是使用 var 关键字var identifier type

var name string
var age int
var b bool

批量声明

var(
   name string
   age int
   b bool
)

变量的初始化

语法

var 变量名 类型 = 表达式

var name string = "Sentiment"
var age int = 18
var b bool = true

类型推导

在声明变量时,可以根据初始化的值进行类型推到,从而省略类型声明

var name = "Sentiment"
var age = 18
var b = true

批量初始化

var name, age, b = "Sentiment", 18, true

短变量声明

函数内部,可以使用:=运算符进行变量声明及其初始化

name:="Sentiment"
age:=18
b:=true

匿名变量

可以接收多个变量,如果有些变量用不到则可用_代替变量名

package main

import "fmt"

func test() (string, int, bool) {
    
   return "Sentiment", 18, true
}
func main() {
    
   name, age, _ := test()
   fmt.Println(name)
   fmt.Println(age)

}

常量

常量声明

语法

const 常量名 类型 = 表达式

package main

import "fmt"

func main() {
    
	const age int = 18 //常规语法
	const PI = 3.14 //可以省略类型

	const (			
		name = "Sentiment"
		b    = true
	)
    
	const x, y = 1, 2 //批量赋值
	fmt.Println(age)
}

同时声明多个常量时,若为赋初值则默认与上方赋值相同

package main

import "fmt"

func main() {
    

   const (
      x = 100
      y
      z
   )

   fmt.Printf("x=%v\n", x)
   fmt.Printf("y=%v\n", y)
   fmt.Printf("z=%v\n", z)
}

结果:

x=100
y=100
z=100

iota

iota可以被认为是一个可编辑器修改的常量,默认值为0,每调用一次+1

package main

import "fmt"

func main() {
    

   const (
      x = iota
      y = iota
      z = iota
   )

   fmt.Printf("x=%v\n", x)
   fmt.Printf("y=%v\n", y)
   fmt.Printf("z=%v\n", z)
}

结果:

x=0
y=1
z=2

可以通过_跳过某个值

package main

import "fmt"

func main() {
    

   const (
      x = iota
      _
      z = iota
   )

   fmt.Printf("x=%v\n", x)
   fmt.Printf("z=%v\n", z)
}

结果:

x=0
z=2

iota插队

package main

import "fmt"

func main() {
    

   const (
      x = iota
      y = 100
      z = iota
   )

   fmt.Printf("x=%v\n", x)
   fmt.Printf("y=%v\n", y)
   fmt.Printf("z=%v\n", z)
}

结果:

x=0
y=100
z=2

感觉没啥应用场景,去找了一下参考参考就行Golang iota 标识符应用教程_梦想画家的博客-CSDN博客_golang itoa

输入

Scan

当使用Scan输入完成后,会得到两个值:

  • count:用户输入值的个数
  • err:用户输入的错误信息
package main

import "fmt"

func main() {
    
	var name string
	var age int
	fmt.Println("请输入用户名:")
	count, err := fmt.Scan(&name, &age)
	fmt.Println(count, err)
	fmt.Printf("用户名为:%s", name)
}

image-20220608204833763

age 为int型若输入错误,则会返回error信息

image-20220608205022326

注:若scan设置了两个参数,则需要两个值都传完才能停止运行,否则会一直等待

Scanln

与Scan的区别在于,回车后就会停止,无论两个值是否传完。

Scanf

支持格式符输入

fmt.Println("请输入用户名:")
fmt.Scanf("name:%s", &name)
fmt.Println(name)

image-20220608211840213

但这种方式有个问题如果在格式符后输入同类型字符,go语言则无法正常解析截断部分

把格式符后边加上age

fmt.Scanf("name:%sage", &name)

可以看到根据格式输入了age,但并没有截断而是一并输出了

image-20220608211953142

这个问题可以用空格分割解决

fmt.Scanf("name:%s age", &name)

image-20220608212106021

数据类型

基本数据类型

布尔型

var b bool

整型

int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64

uint代表无符号型

var a uint
var b uint8
var c int

fmt.Printf("%T\n", a)
fmt.Printf("%T\n", b)
fmt.Printf("%T\n", c)

结果

uint
uint8
int

浮点型

float32, float64

复数型

complex64, complex128

字符串型

string

派生数据类型

数组型

var arr [3]int = [3]int{
    1, 2, 3}
fmt.Printf("%T\n", arr)

结果

[3]int

切片型

感觉就是个可变长数组

var arr []int = []int{
    1, 2, 3}
fmt.Printf("%T\n", arr)

结果

[]int

指针型

a := 100
p := &a
fmt.Printf("%T", p)

结果

*int

函数型

func a() {
    
    
}
func main() {
    
   fmt.Printf("%T", a)
}

结果

func()

还有很多其他类型学到在记吧

字符串

定义方式

主要分为这几种方式,多行定义时用反引号``

   var s string = "Sentiment"
   var s1 = "Tana"
   s2 := "Shelter"
   s3 := ` Sentiment Tana Shelter `
   fmt.Printf("s:%v\n", s)
   fmt.Printf("s1:%v\n", s1)
   fmt.Printf("s2:%v\n", s2)
   fmt.Printf("s3:%v\n", s3)

结果

s:Sentiment
s1:Tana
s2:Shelter
s3:
   Sentiment
   Tana
   Shelter

字符串拼接

加号拼接

跟python一样

var s string = "Sentiment"
var s1 = "Tana"
s2 := s + " " + s1

fmt.Printf("s2:%v\n", s2)

结果

s2:Sentiment Tana

fmt.Sprintf()

var s string = "Sentiment"
var s1 = "Tana"
s2 := fmt.Sprintf("%s,%s", s, s1)

fmt.Printf("s2:%v\n", s2)

结果

s2:Sentiment,Tana

strings.Join()

var s string = "Sentiment"
var s1 = "Tana"
s2 := strings.Join([]string{
    s, s1}, ",")

fmt.Printf("s2:%v\n", s2)

结果

s2:Sentiment,Tana

buffer.WriteString()

var s bytes.Buffer
s.WriteString("Sentiment")
s.WriteString(",")
s.WriteString("Tana")

fmt.Printf("s2:%v\n", s.String()) //注:这里用的是s.String(),否则输出的是十进制

结果

s2:Sentiment,Tana

切片操作

str := "Sentiment,Tana"
n := 10
m := 14

fmt.Println(str[n])   //获取字符串索引为n的字符十进制数
fmt.Println(str[n:m]) //截取n 到 m-1 的字符串
fmt.Println(str[n:])  //从n截取到结束
fmt.Println(str[:m])  //从0截取到 m-1处

结果

84
Tana
Tana
Sentiment,Tana

字符串常用方法

简单试几个方法,剩下的看feng师傅总结的就行

str := "Sentiment,Tana"

fmt.Println(len(str))
fmt.Println(strings.Split(str, ","))
fmt.Println(strings.Contains(str, "Tana"))
fmt.Println(strings.HasPrefix(str, "Sentiment"))
fmt.Println(strings.HasSuffix(str, "Tana"))
fmt.Println(strings.Index(str, "ment"))

结果

14
[Sentiment Tana]
true
true
true
5

feng师傅总结的方法

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

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

strings.Contains(s string, substr string) bool
//判断s中是否包含substr

strings.Index(s string, str string) int
//返回str在s中的第一个索引,-1表示s不包含str

strings.LastIndex(s string, str string) int
//返回str在s中的最后一个索引,-1表示s不包含str

strings.IndexRune(s string, r rune) int
//同上,只不过如果r是非ASCII编码的字符的话。

strings.Replace(str, old, new, n) string
//用于将字符串 str 中的前 n 个字符串 old 替换为字符串 new,并返回一个新的字符串,如果 n = -1 则替换所有字符串 old 为字符串 new

strings.Count(s, str string) int
//计算字符串 str 在字符串 s 中出现的非重叠次数。非重叠的意思是,比如s是egoegoegoego,str是egoego,则Count得到的返回值是2

strings.Repeat(s, count int) string
//重复 count 次字符串 s 并返回一个新的字符串

strings.ToLower(s) string
//将字符串中的 Unicode 字符全部转换为相应的小写字符

strings.ToUpper(s) string
//将字符串中的 Unicode 字符全部转换为相应的大写字符

strings.TrimSpace(s string) string
//去除字符串开头和结尾的空白符号

strings.Trim(s string, cutset string) string
//去除字符串开头和结尾的cutset字符串。

strings.TrimLeft(s string, cutset string) string
//去除字符串开头的cutset字符串

strings.TrimRight(s string, cutset string) string
//去除字符串结尾的cutset字符串

strings.Fields(s string) []string
//利用空白作为分隔符将字符串分割为若干块,并返回一个 slice 。如果字符串只包含空白符号,返回一个长度为 0 的 slice 

strings.Split(s string, sep string) []string
//利用sep作为分隔符将字符串分割为若按块,并返回一个slice

strings.Join(sl []string, sep string) string
//将元素类型为 string 的 slice 使用分割符号来拼接组成一个字符串

格式化输出

占位符

基本占位符

(%v、%+v、%#v、%T)

type Test struct {
    
   Name string
}

func main() {
    
   var name = Test{
    Name: "Sentiment"}
   fmt.Printf("%v\n", name)  //输出值
   fmt.Printf("%+v\n", name) //先输出字段类型,再输出该字段的值
   fmt.Printf("%#v\n", name) //先输出结构体名字值,再输出结构体(字段类型+字段的值)
   fmt.Printf("%T", name)    //输出变量类型

}

结果:

{
    Sentiment}
{
    Name:Sentiment}
main.Test{
    Name:"Sentiment"}
main.Test

布尔占位符

(%t)

var b bool = true
fmt.Printf("%t", b)	//输出布尔值true或false

整数占位符

 %b	二进制表示	
 %c	相应Unicode码点所表示的字符	
 %d	十进制表示	
 %o	八进制表示	
 %q	单引号围绕的字符字面值,由Go语法安全地转义	
 %x	十六进制表示,字母形式为小写 a-f	
 %X	十六进制表示,字母形式为大写 A-F	
 %U	Unicode格式:U+1234,等同于 “U+%04X”
a := 105
b := 222
fmt.Printf("%b\n", a) //二进制
fmt.Printf("%c\n", a) //字符
fmt.Printf("%d\n", a) //十进制
fmt.Printf("%o\n", a) //八进制
fmt.Printf("%q\n", a) //单引号转义
fmt.Printf("%x\n", b) //十六进制小写形式
fmt.Printf("%X\n", b) //十六进制大写形式
fmt.Printf("%U\n", a) //Unicode格式,等价于"U+%04X"

结果

1101001
i
105
151
'i'
de
DE
U+0069

字符串与字节切片

%s	输出字符串表示(string类型或[]byte)
%q	双引号围绕的字符串,由Go语法安全地转义
%x	十六进制,小写字母,每字节两个字符
%X	十六进制,大写字母,每字节两个字符	
name := "Sentiemnt"
name1 := []byte("Tana")   
fmt.Printf("%s\n", name1) //字节型
fmt.Printf("%q\n", name)  //双引号围绕
fmt.Printf("%x\n", name)  //小写十六进制
fmt.Printf("%X\n", name)  //大写十六进制

结果:

Tana
"Sentiemnt"
53656e7469656d6e74
53656E7469656D6E74

指针占位符

(%p)

name := "Sentiemnt"
p := &name
fmt.Printf("%p", p) //指针型

结果

0xc00004c250

运算符

跟其它语言都一样

算数运算符

+、-、*、/、%、++、–

赋值运算符

=、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、!=

关系运算符

==、!=、>、<、>=、<=

逻辑运算符

!、&&、||

位运算符

<<、>>、&、|、!

原网站

版权声明
本文为[Sentiment._]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_54902210/article/details/125206961