当前位置: 首页 > news >正文

Golang学习笔记01

变量的数据类型

整数数据类型

  • 有符号类型 int8 int16 int32 int64
  • 无符号类型 uint8 uint16 uint32 uint64

浮点数据类型

  • float32 4字节
  • float64 8字节

布尔型

package mainimport ("fmt"
)func main() {var s = truefmt.Println(s)
}

字符串

不可变:指的是字符串一旦定义好,其中字符的值不可以改变,如果输入特殊字符,字符串形式为反引号


package main
func main() {var s1 = `var s = trueprintln(s)`println(s1)
}

可以保留原有的输入的内容

类型转化

只能进行强类型转化,不支持自动类型转化,原有的类型不变,只是将数值转化

package mainfunc main() {var a = 101var b = string(a)println(b)
}

注意:int64转化为int8时编译不会出错,但是数值会溢出

其他类型转化为String

使用Sprintf函数进行转化

package mainimport "fmt"func main() {//其他类型转化为String类型//fmt.Sprintf()使用中需要注意转换的格式,int 为%d, float 为%f, bool为%t, byte 为%cvar a int = 20var b float64 = 12.456var c bool = truevar d byte = 'a'var stra, strb, strc, strd stringstra = fmt.Sprintf("%d", a)strb = fmt.Sprintf("%f", b)strc = fmt.Sprintf("%t", c)strd = fmt.Sprintf("%c", d)//输出值的类型%T,占位符%vfmt.Printf("stra type is %T, value is %v \n", stra, stra)fmt.Printf("strb type is %T, value is %v \n", strb, strb)fmt.Printf("strc type is %T, value is %v \n", strc, strc)fmt.Printf("strd type is %T, value is %v \n", strd, strd)
}

使用strconv函数进行转化

package mainimport ("fmt""strconv"
)func main() {var n1 int = 18//参数:第一个参数:传入int64位的一个整数,第二个参数:你需要转化的进制数var s1 = strconv.FormatInt((int64(n1)), 10)fmt.Printf("s1对应的类型是:%T,s1 = %q", s1, s1)println()//参数:第一个参数:需要转化的数,第二个参数:‘f’(-ddd.dddd),第三个参数:小数点的保留位数,第四个参数:转化为int64var n2 float64 = 4.21var s2 = strconv.FormatFloat(n2, 'f', 4, 64)fmt.Printf("s2对应的类型是:%T,s2 = %q", s2, s2)println()var n3 = truevar s3 = strconv.FormatBool(n3)fmt.Printf("s3对应的类型是:%T,s3 = %q", s3, s3)
}//运行结果:
//s1对应的类型是:string,s1 = "18"
//s2对应的类型是:string,s2 = "4.2100"
//s3对应的类型是:string,s3 = "true" 

string类型转化为其他类型

package mainimport ("fmt""strconv"
)func main() {var a = "123"var a1, err = strconv.ParseInt(a, 10, 64)fmt.Printf("类型是:%T,值是%v,%v", a1, a1, err)println()//非数字字符不能转化为intvar b = "hello"var b1, err1 = strconv.ParseInt(b, 10, 64)fmt.Printf("类型是:%T,值是%v,%v", b1, b1, err1)println()var c = "true"var c1, _ = strconv.ParseBool(c)fmt.Printf("类型是:%T,值是%v", c1, c1)
}

指针

package mainfunc main() {var i int = 10println("i的值", i)//指针类型var ptr *int = &iprintln("i的地址", ptr)println("ptr的地址", &ptr)println("ptr指向的值", *ptr)
}
/*
输出结果:
i的值 10
i的地址 0xc00005ff28
ptr的地址 0xc00005ff38
ptr指向的值 10
*/

注意点

  1. 指针可以改变具体的值
  2. 指针变量接受的是地址
  3. 指针的地址不可以不匹配

流程控制语句

package mainimport "fmt"func main() {//流程控制语句var a = 10if a > 10 {fmt.Println(1)} else {fmt.Println(2)}//switch循环switch 10 / 2 {case 1:println(1)case 2:println(2)default:println(3)}//for循环for i := 0; i < 10; i++ {fmt.Printf("%v \n", i)}//for range遍历:每个结果的索引被i接收,每个结果被val接收,遍历是对字符遍历var str = "hello,go语言"for i, val := range str {fmt.Printf("i=%v,val=%q \n", i, val)}/*	输出为:i=0,val='h'i=1,val='e'i=2,val='l'i=3,val='l'i=4,val='o'i=5,val=','i=8,val='g'i=9,val='o'i=10,val='语'i=13,val='言'*/
}

goto用法

package mainimport "fmt"func main() {fmt.Println(1)fmt.Println(2)if 1 == 1 {goto label1}fmt.Println(3)fmt.Println(4)label1:fmt.Println(5)
}

函数

package mainimport "fmt"func main() {//调用var res = sum(1, 2)fmt.Println(res)
}func sum(a int, b int) int {return a + b
}

首字母大写该函数可以被本包文件和其他包使用(public),首字母小写只能被本包使用(private)


通过地址交换两个数

package mainimport "fmt"func main() {//调用var a = 10var b = 20fmt.Println(a, b)swap(&a, &b)fmt.Println(a, b)
}func swap(a *int, b *int) {var t = *a*a = *b*b = t
}

ps:go中不支持重载,支持可变参数

go函数可以作为一个数据类型,赋值给一个变量

package mainimport "fmt"func test(num int) {fmt.Println(num)
}func main() {var a = testfmt.Printf("a的类型是%T,test的类型为%T \n", a, test) //a的类型是func(int),test的类型为func(int)10a(10) //等价与test(10)
}

自定义数据类型

package mainimport "fmt"func main() {//自定义数据类型:相当于起别名type myInt intvar num1 myInt = 10//num1的类型是main.myInt,num1的值为10fmt.Printf("num1的类型是%T,num1的值为%v", num1, num1)
}

函数的返回值可以支持命名,里面的顺序可以不一样

package mainimport "fmt"func test1(num1 int, num2 int) (sum int, sub int) {sub = num1 - num2sum = num1 + num2return sum, sub
}func main() {var n1 = 10var n2 = 5var sum, sub = test1(n1, n2)fmt.Println(sum, sub)
}

init函数

每一个源文件包含一个init函数,该函数会在main函数调用前,被go框架所执行

package mainimport "fmt"func init() {fmt.Println("init被执行")
}func main() {fmt.Println("main被执行")
}
//init被执行
//main被执行

匿名函数

只希望被调用一次,可以使用到匿名函数,定义的同时被调用

package mainimport "fmt"// 让匿名函数在全局有效
var Mul = func(num1 int, num2 int) int {return num1 * num2
}func main() {//定义匿名函数var res = func(num1 int, num2 int) int {return num1 + num2}(10, 20)fmt.Println(res)//将匿名函数赋值给一个变量,这个变量实际上是函数类型的变量//sub等价于匿名函数sub := func(num1 int, num2 int) int {return num1 - num2}//调用subres01 := sub(50, 20)fmt.Println(res01)var res02 = Mul(2, 3)fmt.Println(res02)
}

闭包

返回的匿名函数+匿名函数以外的变量 = 闭包

闭包的值会一直保存到内存中

package mainimport "fmt"// 闭包
func getSum() func(int) int {var n = 10return func(i int) int {n = n + ireturn n}
}
func main() {f := getSum()fmt.Println(f(1))//11fmt.Println(f(1))//12
}

defer 关键字

package mainimport "fmt"func main() {fmt.Println(add(30, 60))
}
func add(num1 int, num2 int) int {//在Golang中程序遇到关键字defer不会立即执行,而是将defer后的语句压入栈中,继续执行函数后的语句defer fmt.Println("num1=", num1)defer fmt.Println("num2=", num2)var sum = num1 + num2fmt.Println("sum=", sum)return sum
}
/*
按照先进后出的规则
sum= 90
num2= 60
num1= 30
90*/

应用场景:想要关闭某些资源时,在前面加入defer关键字,因为defer有延迟机制

系统函数

package mainimport ("fmt""strconv""strings"
)func main() {//1.统计字符串var str = "golang你好"  //Golang中汉字是utf-8字符集,一个汉字三个字节fmt.Println(len(str)) //12//2.对字符串进行遍历 方式一//索引为0,值为g//索引为1,值为o//索引为2,值为l//索引为3,值为a//索引为4,值为n//索引为5,值为g//索引为6,值为你//索引为9,值为好for i, value := range str {fmt.Printf("索引为%d,值为%c \n", i, value)}//方式二利用切片//'g''o''l''a''n''g''你''好'var r = []rune(str)for i := 0; i < len(r); i++ {fmt.Printf("%q", r[i])}println()//3.字符串转化整数n, _ := strconv.Atoi("66")fmt.Println(n)//4.整数转为字符串var str1 = strconv.Itoa(10)fmt.Println(str1)//5.统计一个字符串有多少指定的子串var count = strings.Count("javaandgolang", "a")fmt.Println(count) //4//6.不区分大小写的字符串的比较fmt.Println(strings.EqualFold("go", "GO")) //true//7.查看子串是否在字符串内var res = strings.Contains("golang", "o")println(res)//8.返回一个子串在字符串中第一次出现的索引,没有就返回-1var index = strings.Index("golang", "a")fmt.Println(index) //3
}
package mainimport ("fmt""strings"
)func main() {//9.字符串替换 n=-1表示全部替换,替换两个n=2var str = strings.Replace("golangandjava", "go", "golang", 2)fmt.Println(str)//10.切割var str1 = strings.Split("go-java-c++", "-")fmt.Println(str1) //[go java c++]//11.大小写转化strings.ToLower("A")strings.ToUpper("a")//12.去除空格strings.TrimSpace(" goandjava ")//13.去除左右两边指定字符strings.Trim("-javago-", "-")//14.判断字符是否是指定字符开头,结尾strings.HasPrefix("http://123.123", "http")strings.HasSuffix("http://123.123", "123")
}

日期函数

package mainimport ("fmt""time"
)func main() {//日期函数var now = time.Now()//返回值的类型是一个结构体fmt.Printf("类型是%T \n", now) //time.Timefmt.Println(now)            //2024-06-13 14:25:35.9049279 +0800 CST m=+0.002579401year := now.Year()month := now.Month()day := now.Day()fmt.Println(year, month, day)
}

内置函数

不需要导包,直接使用

package mainimport "fmt"func main() {var str = "golang"fmt.Println(len(str))//new函数分配内存,new函数的实参是一个类型而不是具体数值,返回值是对应类型的指针var num = new(int)fmt.Printf("num的类型是%T,num的值为%v,num的地址为%v,num指向的值为%v", num, num, &num, *num)//num的类型是*int,num的值为0xc00000a0f8,num的地址为0xc000062030,num指向的值为0
}

错误处理机制

使用defer+recover管理错误

package mainimport "fmt"func main() {//利用defer+recover+匿名函数捕获异常defer func() {var err = recover()if err != nil {fmt.Println("错误被捕获")fmt.Println("错误是", err)}}()var num1 = 10var num2 = 0var res = num1 / num2fmt.Println(res)
}

自定义错误

package mainimport ("errors""fmt"
)func main() {err := test()if err != nil {fmt.Println("自定义错误", err)}fmt.Println("正常执行下面逻辑")
}func test() (err error) {num1 := 10num2 := 0if num2 == 0 {//抛出自定义异常return errors.New("除数不能为0")} else {fmt.Println(num1 / num2)return nil}
}
//自定义错误 除数不能为0
//正常执行下面逻辑

数组

package mainimport "fmt"func main() {var num [3]intnum[0] = 1num[1] = 2num[2] = 3var sum intfor i := 0; i < len(num); i++ {sum += num[i]}fmt.Println(sum)//初始化数组var arr [3]int = [3]int{10, 11, 12}fmt.Println(arr)var arr2 = [...]int{1, 2, 3, 4}fmt.Println(arr2)var arr3 = [...]int{1: 10, 2: 1, 0: 5}fmt.Println(arr3)
}

数组默认是值传递,想要在外部修改原有的值,需要传递地址

package mainimport ("fmt"
)func main() {var arr = [...]int{1, 2, 3}fmt.Println("原数组的值为", arr)test(&arr)fmt.Println("修改后数组的值为", arr)//原数组的值为 [1 2 3]//修改后数组的值为 [4 2 3]
}func test(arr *[3]int) {arr[0] = 4
}

二维数组

package mainimport "fmt"func main() {var arr = [2][3]int{{1, 2, 3}, {4, 5, 6}}fmt.Println(arr)
}

切片

建立在数组上的一种抽象,构建在数组之上,并且提供了更强大的能力,
是对数组一个连续片段的引用,所以切片是一种引用类型,这个片段可以是整个数组
或者是由起始和终结标识符的一些项的子集

package mainimport "fmt"func main() {var arr = [6]int{1, 2, 3, 4, 5, 6}//切片构建在数组之上,左闭右开var slice = arr[1:3]fmt.Println(slice)//切片的构建var slice1 = make([]int, 4, 20)fmt.Println("slice1的长度", len(slice1))fmt.Println("slice1的最大容量", cap(slice1))var slice2 = []int{1, 2, 3}fmt.Printf("slice2的类型%T \n", slice2)fmt.Println("slice2的长度", len(slice2))fmt.Println("slice2的最大容量", cap(slice2))
}

可以实现动态扩容,底层是创建一个新数组将老数组复制到新数组中

package mainimport "fmt"
func main() {var slice2 = []int{1, 2, 3}var slice3 = append(slice2, 4, 5)fmt.Println(slice3)//1,2,3,4,5
}

映射

go中内置的数据类型,将键值进行关联,通过key获取val

package mainimport "fmt"func main() {//只声明是不会分配内存空间的var a = make(map[int]string, 10)a[1] = "张三"a[2] = "李四"a[3] = "王五"fmt.Println(a)var b = make(map[int]string)b[1] = "张三"b[2] = "李四"fmt.Println(b)var c = map[int]string{1: "张三",2: "李四",}fmt.Println(c)
}

面向对象

package mainimport "fmt"type Person struct {Name stringAge  int
}func main() {//方式一var p1 = Person{Name: "张三",Age:  18,}fmt.Println(p1)//方式二创建结构体的指针,应该给地址指向的字段赋值var p2 *Person = new(Person)(*p2).Name = "李四"(*p2).Age = 20fmt.Println(*p2)//方式三var p3 = &Person{"王五",30,}fmt.Println(p3)
}
package mainimport "fmt"type A struct {Num int
}// 方法与结构体是绑定关系,如果其他类型调用test会报错,并且是值传递
func (a A) test() {fmt.Println(a.Num)
}func main() {var p = A{Num: 1,}p.test()
}a[3] = "王五"fmt.Println(a)var b = make(map[int]string)b[1] = "张三"b[2] = "李四"fmt.Println(b)var c = map[int]string{1: "张三",2: "李四",}fmt.Println(c)
}

相关文章:

  • CMU最新论文:机器人智慧流畅的躲避障碍物论文详细讲解
  • 卡尔曼滤波原理及应用(一)
  • Web前端后端架构:构建高效、稳定与可扩展的互联网应用
  • cnvd_2015_07557-redis未授权访问rce漏洞复现-vulfocus复现
  • 【0基础学爬虫】爬虫基础之自动化工具 DrissionPage 的使用
  • vite-plugin-mock前端自行模拟接口返回数据的插件
  • PHP开发的爱情盲盒交友系统网站源码
  • 数据结构——排序
  • 矩阵的迹(Trace)
  • 基于ChatGPT的大型语言模型试用心得
  • 【日记】第一次养植物,没什么经验……(781 字)
  • AI时代新爬虫:网站自动转LLM数据,firecrawl深度玩法解读
  • Footer组件在home 、search 显示,在登录、注册隐藏
  • 课设--学生成绩管理系统(一)
  • Nexus搭建maven私有仓库
  • “大数据应用场景”之隔壁老王(连载四)
  • cookie和session
  • Elasticsearch 参考指南(升级前重新索引)
  • JavaScript实现分页效果
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Kibana配置logstash,报表一体化
  • overflow: hidden IE7无效
  • rc-form之最单纯情况
  • Spark学习笔记之相关记录
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 初探 Vue 生命周期和钩子函数
  • 简单基于spring的redis配置(单机和集群模式)
  • 解析 Webpack中import、require、按需加载的执行过程
  • -- 数据结构 顺序表 --Java
  • 数组的操作
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 原生Ajax
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​​​【收录 Hello 算法】10.4 哈希优化策略
  • ​Redis 实现计数器和限速器的
  • ​卜东波研究员:高观点下的少儿计算思维
  • #pragma multi_compile #pragma shader_feature
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (C语言)fgets与fputs函数详解
  • (done) 两个矩阵 “相似” 是什么意思?
  • (SERIES12)DM性能优化
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (转)程序员技术练级攻略
  • (转载)从 Java 代码到 Java 堆
  • ./configure、make、make install 命令
  • .gitignore文件忽略的内容不生效问题解决
  • .Net 8.0 新的变化
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .net(C#)中String.Format如何使用
  • .Net--CLS,CTS,CLI,BCL,FCL
  • @FeignClient注解,fallback和fallbackFactory