export GOPATH=/Users/as4k/gopro
package main
import "fmt"
func main() {
var name string
var age int
fmt.Println("请输入用户名:")
// 当使用Scan时,会提示用户输入
// 用户输入完成之后,会得到两个值:count,用户输入了几个值;err,用输入错误则是错误信息
_, err := fmt.Scan(&name, &age)
if err == nil {
fmt.Println(name, age)
} else {
fmt.Println("用户输入数据错误", err)
}
// 特别说明:fmt.Scan 要求输入两个值,必须输入两个,否则他会一直等待。
}
// 测试:运行代码,输入两个数据,空格分割,如 ming 20
##### 1
if true {
fmt.Println("666")
} else{
fmt.Println("999")
}
##### 2
if 1 > 2 {
fmt.Println("666")
} else {
fmt.Println("999")
}
##### 3
flag := false
if flag {
fmt.Println("条件成立")
} else{
fmt.Println("条件不成立")
}
##### 4
package main
import "fmt"
func main() {
// 判断用户名密码是否正确
var username, password string
fmt.Print("请输入用户名:")
fmt.Scanln(&username)
fmt.Print("请输入密码:")
fmt.Scanln(&password)
if username == "root" && password == "123456" {
fmt.Println("欢迎登录")
} else {
fmt.Println("用户名或密码错误")
}
}
##### 5
package main
import "fmt"
func main() {
// 请输入用户名校验是否是VIP
var username string
fmt.Print("请输入用户名:")
fmt.Scanln(&username)
if username == "alex" || username == "eric" {
fmt.Println("欢迎使用")
} else {
fmt.Println("请充钱")
}
}
##### 6 成绩判断
package main
import "fmt"
func main() {
var score int
fmt.Print("请输入你的分数:")
fmt.Scanln(&score)
if score >= 90 {
fmt.Println("优秀")
} else if score >= 80 {
fmt.Println("良好")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("挂科")
}
}
##### 7 嵌套判断
package main
import "fmt"
func main() {
fmt.Println("欢迎致电10086,1.话费相关;2.业务办理;3.人工服务。")
var number int
fmt.Scanln(&number)
if number == 1 {
fmt.Println("话费服务,1.交话费;2.查询。")
var n1 int
fmt.Scanln(&n1)
if n1 == 1 {
fmt.Println("缴话费啦")
} else if n1 == 2 {
fmt.Println("查话费了")
} else {
fmt.Println("输入错误")
}
} else if number == 2 {
fmt.Println("业务办理")
} else if number == 3 {
fmt.Println("人工服务")
} else {
fmt.Println("输入错误")
}
// 建议:条件的嵌套不要太多
}
定义变量方式1
==================================
var name string = "武沛齐"
var age int = 18
定义变量方式2
==================================
var name = "武沛齐"
var age = 18
定义变量方式3
==================================
name := "武沛齐"
age := 18
定义变量方式4
==================================
var name string
name = "武沛齐"
定义变量方式5 定义多个变量 因式分解
==================================
var (
name = "武沛齐"
age = 18
gender string
)
var age,age2 = 10,11
var c1, c2, c3 = "chaoge", 18, 99.99
特殊变量,占位符 _
==================================
package main
import "fmt"
func Person(a1 int, n1 string) (int, string) {
return a1, n1
}
func main() {
_, name := Person(18, "好嗨哦")
fmt.Println(name)
}
变量的默认值
==================================
注意:如果变量只声明不赋值,Go内部其实会给变量默认设置值:int 为 0,float 为 0.0,bool 为 false,string 为空字符串,指针为 nil 。
变量名要求
==================================
变量名由字母、数字、下划线组成,且首个字符不能为数字。
全局变量
==================================
package main
import "fmt"
// 声明全局变量
var country string = "中国"
// 或可使用 var country = "中国"
// 不可使用 country := "中国"
func main() {
fmt.Println(country)
country = "China"
fmt.Println(country)
}
// Go中的全局变量比较特殊,如果全局变量名首字母小写,则只能被当前包中的go文件使用,外部无法使用;如果首字母大写,则任意文件都使用全局变量。
// 可简单理解为:首字母大写表写公有,首字母小写表示私有(当前包的go文件所有)。
局部变量
==================================
Go中的变量有作用域之分,每个大括号就是一个作用域,每个作用域中都可定义相关的局部变量。
package main
import (
"fmt"
)
func main() {
// 声明局部变量,在当前函数可用
var name string = "武沛齐"
fmt.Println(name)
if true {
// 生命局部变量,在当前if中可用
var age = 18
fmt.Println(age)
}
// 报错,age在if括号的作用域中
// fmt.Println(age)
}
未使用的常量不会引发编译错误。(这点和变量不一样)
const World string = "世界" //常量定义且赋值
const x, y int = 1, 2 //多常量初始化
const s1 = "Hello golang" //常量类型推断,字符串类型
//常量组
const (
e = 2.71828182845904523536028747135266249775724709369995957496696763
pi = 3.14159265358979323846264338327950288419716939937510582097494459
b bool = true
)
//常量组,可以除了第一个外其他的常量右边的初始化表达式可以省略
//如果省略初始化表达式,默认使用前面常量的表达式
//与上一个常量相同
const (
c1=1
c2
c3
c4="c44444"
c5
)
/*
输出结果
1
1
1
c44444
c44444
*/
iota用于生成一组相似规则初始化的常量,在const常量声明的语句中,第一个常量所在行,iota为0,之后每一个常量声明加1
例如time包的例子,一周7天,每天可以定义为常量,1~6,周日为0,这种类型也称为枚举
package main
import (
"fmt"
)
const (
Sunday = iota
Monday //通常省略后续行表达式
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func main() {
fmt.Println(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
}
//output: 0 1 2 3 4 5 6
package main
import (
"fmt"
"unsafe"
)
func main() {
var n1 = 100
fmt.Printf("n1的类型:%T \n", n1)
var n2 int64 = 100
//unsafe包底下的Sizeof函数,返回变量占用字节数
fmt.Printf("n2的类型是:%T,占用的字节数是%d \n", n2, unsafe.Sizeof(n2))
var price float32 = 100.02
fmt.Printf("price类型是:%T,值是%v \n", price, price)//%T 类型 %v 默认值
}
package main
import "fmt"
func main() {
var c1 byte = 'a'
var c2 byte = '2' //字符的2
//直接输出byte的值,也就是输出对应的字符的码值
fmt.Println("c1=", c1)
fmt.Println("c2=", c2)
//输出字符的值,需要格式化输出
fmt.Printf("c1值=%c c2值=%c\n", c1, c2)
//如果保存的字符对应码大于255,应该使用int而不是byte,否则overflows byte异常
//var c3 int = '皮' //正确
//var c4 byte = '皮' //overflows byte 报错
var c4 int = 22269
fmt.Printf("c4=%c\n", c4)
}
package main
import "fmt"
func main() {
//识别转义符
var story string = "妖怪\n放了我师父"
fmt.Println(story)
//反引号,以原生形式输出,包括特殊字符,防止注入攻击
story2 := `
你看这个灯,它又大又亮
你好
我是银角大王吧,你吃了\n吗?
`
fmt.Println(story2)
}
//字符串拼接,识别空格
str3 := "你好" + " 我是孙悟空"
fmt.Println(str3)
package main
import "fmt"
func main() {
str3 := "hello world"
//索引取出值的码值,格式化输出
fmt.Printf("str3=%c\n",str3[1])
//输出str3的长度
fmt.Println(len(str3))
}
package main
import "fmt"
func main() {
myname := "hello world"
//for _, ret := range myname {
// fmt.Printf("ret=%c\n", ret)
//}
for k, ret := range myname {
fmt.Println(k,ret)
}
}
package main
import "fmt"
func main() {
myname := "hello world"
m1 := []rune(myname) //转化为[]int32的切片,rune是int32的别名
m1[4] = '皮' //修改索引对应的值
myname = string(m1) //类型强转,rune转为string
fmt.Println(myname)
//output: hell皮 world
}
一个布尔类型的值只有两种:true 和 false
package main
import (
"fmt"
"unsafe"
)
func main() {
var b = true
fmt.Println("b=", b)
fmt.Println("b字节数=", unsafe.Sizeof(b))
}
官网模块 https://golang.org/pkg/strings/
package main
import (
"fmt"
"strings"
)
func main() {
str := "hello world"
//判断是不是以某个字符串开头,返回布尔值
res0 := strings.HasPrefix(str, "http://")
res1 := strings.HasPrefix(str, "hello")
fmt.Printf("res0 is %v\n", res0)
fmt.Printf("res1 is %v\n", res1)
//判断是不是以某个字符串结尾
res3 := strings.HasSuffix(str, "http://")
res4 := strings.HasSuffix(str, "world")
fmt.Printf("res3 is %v\n", res3)
fmt.Printf("res4 is %v\n", res4)
//判断字符在字符串中首次出现的索引位置,没有返回-1
res5 := strings.Index(str, "o")
res6 := strings.Index(str, "x")
fmt.Printf("res5 is %v\n", res5)
fmt.Printf("res6 is %v\n", res6)
//返回字符最后一次出现的索引位置,没有返回-1
res7 := strings.LastIndex(str, "o")
res8 := strings.LastIndex(str, "x")
fmt.Printf("res7 is %v\n", res7)
fmt.Printf("res8 is %v\n", res8)
//字符串替换
res9 := strings.Replace(str, "world", "golang", 2)
res10 := strings.Replace(str, "world", "golang", 1)
//trings.Replace("原字符串", "被替换的内容", "替换的内容", 替换次数)
//原字符串中有2个world,才能替换2次
fmt.Printf("res9 is %v\n", res9)
fmt.Printf("res10 is %v\n", res10)
//求字符在字符串中出现的次数,不存在返回0次
countTime0 := strings.Count(str, "h")
countTime1 := strings.Count(str, "x")
fmt.Printf("countTime0 is %v\n", countTime0)
fmt.Printf("countTime1 is %v\n", countTime1)
//重复几次字符串
res11 := strings.Repeat(str, 0)
res12 := strings.Repeat(str, 1)
res13 := strings.Repeat(str, 2)
// strings.Repeat("原字符串", 重复次数)
fmt.Printf("res11 is %v\n", res11)
fmt.Printf("res12 is %v\n", res12)
fmt.Printf("res13 is %v\n", res13)
//字符串改大写
res14 := strings.ToUpper(str)
fmt.Printf("res14 is %v\n", res14)
//字符串改小写
res15 := strings.ToLower(str)
fmt.Printf("res15 is %v\n", res15)
//去除首尾的空格
res16 := strings.TrimSpace(str)
fmt.Printf("res16 is %v\n", res16)
//去除首尾指定的字符,遍历l、d、e然后去除
res17 := strings.Trim(str, "ld")
fmt.Printf("res17 is %v\n", res17)
//去除开头指定的字符
res18 := strings.TrimLeft(str, "he")
fmt.Printf("res18 is %v\n", res18)
//去除结尾指定的字符,遍历d、l、r
res19 := strings.TrimRight(str, "dlr")
fmt.Printf("res19 is %v\n", res19)
//用指定的字符串将string类型的切片元素结合
str1 := []string{"hello", "world", "hello", "golang"}
res20 := strings.Join(str1, "+")
fmt.Printf("res20 is %v\n", res20)
}
//1. 指针默认值nil
//2. 通过&(取地值符)取变量地址
//3. 通过*(取值符)透过指针访问目标值
package main
import (
"fmt"
)
func main() {
var name string = "yugo"
//查看name变量的内存地址,通过&name取地址
fmt.Printf("name的内存地址:%v\n", &name)
//指针变量,存的是内存地址
//ptr指针变量指向变量name的内存地址
var ptr *string = &name
fmt.Printf("指针变量ptr的内存地址:%v\n", ptr)
//获取指针变量的值,用*ptr
//*ptr表示读取指针指向变量的值
fmt.Printf("指针变量ptr指向的值是:%v\n", *ptr)
}
https://pythonav.com/wiki/detail/4/47/
数组是多个相同类型数据的组合,且长度固定,无法扩容
####1
package main
import "fmt"
func main() {
var a1 = [...]int{1, 2, 3, 4, 5, 6}
//通过索引取值
for i := 0; i < len(a1); i++ {
fmt.Println(a1[i])
}
//for循环遍历数组,索引和值,index可以省略用占位符_
for index, value := range a1 {
fmt.Println(index, value)
}
}
####2
package main
import (
"fmt"
)
//函数接收值类型,默认有值拷贝
func test(arr [3]int) {
arr[0] = 66
}
//函数修改原本数组,需要使用引用传递
func test2(arr *[3]int) {
(*arr)[0] = 66 //可以缩写arr[0]=66 编译器自动识别,arr是指针类型
}
func main() {
//声明arr数组,需要考虑传递函数参数时,数组的长度一致性
arr := [3]int{11, 22, 33}
//test函数不会修改数组
test(arr)
fmt.Println(arr)
//test2修改了数组
test2(&arr)
fmt.Println(arr)
}
https://pythonav.com/wiki/detail/4/48/
//1. 切片是可动态变化的序列,是对数组的引用,引用类型,遵循引用传递的机制
//2. slice类型写作[]T,T是slice元素类型,var s1 []int,s1就是切片变量
/*
区间索引时,Go言里也采用左闭右开形式
比如
a = [1, 2, 3, 4, 5]
a[0:3] = [1, 2, 3] 不包含最后一个元素
比如
s[m:n]这个切片,
0 ≤ m ≤ n ≤ len(s),包含 n-m 个元素
*/
package main
import "fmt"
func main() {
//创建一个数组
var array1 [5]int = [...]int{11, 22, 33, 44, 55}
/*
创建切片,通过对数组的索引切片
s1 是切片名
array1[1:3]代表slice引用数组区间,索引1到索引3的值,注意取头不取尾,
*/
s1 := array1[1:4]
fmt.Println(array1)
fmt.Println(s1)
fmt.Println(len(s1))
fmt.Println(cap(s1))
}
/*
运行结果
[11 22 33 44 55] //原本数组
[22 33 44] //切片的值
3 //切片元素长度
4 //切片容量
*/
//1. map是key-value类型数据结构,读作(哈希表、字典),是一堆未排序的键值对集合。
//2. map的key必须是支持相等运算符==、!=的类型,如int、bool、channel、string、pointer、array、sruct、interface。
package main
import "fmt"
func main() {
/*
map声明语法
var 变量名 map[keytype]valuetype
var m1 map[string]string
var m2 map[int]string
var m3 map[int]map[string]string//map的value又是map
注意map声明不会分配内存,必须make初始化才可以使用
*/
//声明map方式一
//make函数可以合理申请一大块内存,避免后续扩张时性能问题
var m1 map[string]string
//标注map的初始容量为10
m1 = make(map[string]string, 10)
m1["一号"] = "大狗子"
m1["二号"] = "二狗子"
fmt.Println(m1)
//声明方式二
m2 := make(map[string]string)
m2["男"] = "小黑"
m2["女"] = "小女"
fmt.Println(m2)
//声明方式三
m3 := map[string]string{
"坦克": "德玛西亚",
"射手": "伊泽瑞尔",
"辅助": "星女",
}
m3["打野"] = "赵信"
fmt.Println(m3)
}
https://pythonav.com/wiki/detail/4/50/
//1. Golang支持OOP面向对象编程
//2. Go的结构体struct如同python的class
//3. 将一类事务特性提取出一个新的数据类型,就是结构体
//4. 通过结构体可以创建多个实例
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
//声明方式
p1 := Person{"小黑", 18} //有序赋值,并且必须包含所有字段,否则报错
p2 := Person{Age: 18} //关键词赋值,未赋值字段有空值
fmt.Println(p1)
fmt.Println(p2)
}
https://pythonav.com/wiki/detail/4/51/
package main
import "fmt"
func main() {
var age int
fmt.Println("请输入您的年纪:")
//获取用户输入,传入变量地址,防止值拷贝
fmt.Scanln(&age)
if age > 18 {
fmt.Println("你已经是个18岁的小伙子了!!加油")
}
}
package main
import "fmt"
func main() {
var week int
fmt.Println("请输入星期几:")
fmt.Scanln(&week)
switch week {
case 1:
fmt.Println("星期一,上班!!")
case 2, 3, 4, 5:
fmt.Println("星期二到星期五,你还得上班!!")
case 6:
fmt.Println("周六你就想休息?加班!!")
case 7:
fmt.Println("老子迟早要辞职,终于能休息了!!")
default:
fmt.Println("输入错误你就必须得上班!!")
}
}
package main
import "fmt"
func main() {
//创建方式一,循环条件是布尔值表达式
num := 0
for num <= 10 {
fmt.Println("我说老男孩golang 你说哟", num)
num++
}
//创建方式二,无限循环,go不存在while语法
num1 := 0
for {
if num1 <= 10 {
fmt.Println("人生苦短 说go就go", num1)
} else {
break //超出了就终止这个for循环
}
num1++ //等于num1=num1+1
}
fmt.Println("----------")
//创建方式三 for-range 用于遍历字符串、数组
var teacher = "wu pei qi"
//字符串可以用索引取值,注意格式化输出的时候,要输出码值对应的字符 %c 格式化
for i := 0; i < len(teacher); i++ {
fmt.Printf("%c\n", teacher[i])
}
fmt.Println("----------")
//创建方式四
student := "chaoge牛逼"
//for range遍历,是按照字符方式遍历,支持中文
for k, v := range student {
fmt.Printf("索引:%v 值:%c\n", k, v)
}
fmt.Println("----------")
//传统遍历字符串是按字节遍历,汉字对应utf8编码是3个字节
var class1 string = "python全栈开发班"
//必须转化为[]rune切片类型,方可使用
class2 := []rune(class1)
for i := 0; i < len(class2); i++ {
fmt.Printf("%c\n", class2[i])
}
}
循环限制三次登录
package main
import "fmt"
func main() {
var name string
var pwd string
var logincache = 3
//循环限制三次登录
for i := 1; i <= 3; i++ {
fmt.Println("请输入账号:")
fmt.Scanln(&name)
fmt.Println("请输入密码:")
fmt.Scanln(&pwd)
if name == "alex" && pwd == "alex3714" {
fmt.Println("欢迎鸡汤王归来!!")
break
} else {
logincache-- //每次登录失败减一
fmt.Printf("你还有%v次机会尝试,老铁\n", logincache)
}
}
}
goto
package main
import "fmt"
func main() {
var num int = 100
fmt.Println("num值100")
if num > 90 {
goto label
//此处代码已经不走,直接goto了
fmt.Println("呵呵")
}
fmt.Println("我是占位符")
fmt.Println("我是占位符")
fmt.Println("我是占位符")
fmt.Println("我是占位符")
fmt.Println("我是占位符")
//触发了goto,进入本次标签
label:
fmt.Println("由于触发了goto,进入到我这里了")
fmt.Println("我也是占位符")
fmt.Println("我也是占位符")
fmt.Println("我也是占位符")
}
break
package main
import "fmt"
func main() {
var num int = 10
for num < 50 {
fmt.Printf("a的值是:%v\n", num)
num++
if num > 30 {
break //跳出for循环
}
}
}
break label
package main
import (
"fmt"
)
func main() {
fmt.Println("主程序开始执行")
Exit:
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
if i+j > 15 {
fmt.Println("程序结束")
break Exit
}
}
}
fmt.Println("已跳出循环体")
}
continue语句
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* for 循环 */
for a < 20 {
if a == 15 {
/* 当a等于15时,跳出循环,让a++,等于16,跳过本次循环 */
a++
continue
}
fmt.Printf("a 的值为 : %d\n", a)
a++
}
}
return语句
package main
import "fmt"
func main() {
for i := 0; i <= 10; i++ {
if i == 5 {
return //直接退出main函数了
}
fmt.Printf("本次循环次数:%d\n", i)
}
//永远走不带这里了,第五次for循环时候,直接return了
fmt.Println("循环结束,走到了我")
}
https://pythonav.com/wiki/detail/4/52/
关键词
defer
func 函数名(形参列表)(返回值列表){
执行代码
return 返回值列表
}
init函数 每个源文件都会包含一个inti函数,该函数在main函数之前被执行
package main
import "fmt"
func init() {
fmt.Println("init函数一般完成初始化工作,如数据库驱动连接等")
}
func main() {
fmt.Println("我是主程序")
}
// 全局变量 --> init函数 --> main函数
面试题:如果再包导入中,main.go和utils.go都有变量加载,init函数,执行流程是?
main.go是程序入口
↓
自上而下,进入import导入
↓
优先进入utils.go 加载全局变量 这是第一步
↓
执行utils.go的init函数 第二步
↓
完毕后,回到main.go的全局变量 第三步
↓
执行main.go的init函数 第四步
↓
执行main.go的主程main()函数 第五步
统计字符串长度,按字节 len(str)
字符串遍历,处理中文 r:=[]rune(str)
字符串转整数 n, err := strconv.Atoi("12")
整数转字符串 str = strconv.Itoa(12345)
字符串 转 []byte var bytes = []byte("hello go")
[]byte 转 字符串 str = string([]byte{97, 98, 99})
10 进制转 2, 8, 16 进制: str = strconv.FormatInt(123, 2) // 2-> 8 , 16
查找子串是否在指定的字符串中 strings.Contains("seafood", "foo") //true
统计一个字符串有几个指定的子串 strings.Count("ceheese", "e") //4
不区分大小写的字符串比较(==是区分字母大小写的) fmt.Println(strings.EqualFold("abc", "Abc")) // true
返回子串在字符串第一次出现的 index 值,如果没有返回-1 strings.Index("NLT_abc", "abc") // 4
返回子串在字符串最后一次出现的 index,如没有返回-1 strings.LastIndex("go golang", "go")
将指定的子串替换成 另外一个子串 strings.Replace("go go hello", "go", "go 语言", n) ,n 可以指 定你希望替换几个,如果 n=-1 表示全部替换
按照指定的某个字符,为分割标识,将一个字符串拆分成字符串数组 strings.Split("hello,wrold,ok", ",")
将字符串的字母进行大小写的转换: strings.ToLower("Go") // go strings.ToUpper("Go") // GO
将字符串左右两边的空格去掉: strings.TrimSpace(" tn a lone gopher ntrn ")
将字符串左右两边指定的字符去掉 : strings.Trim("! hello! ", " !")
将字符串左边指定的字符去掉 : strings.TrimLeft("! hello! ", " !")
将字符串右边指定的字符去掉 :strings.TrimRight("! hello! ", " !")
判断字符串是否以指定的字符串开头: strings.HasPrefix("ftp://192.168.10.1", "ftp")
判断字符串是否以指定的字符串结束: strings.HasSuffix("NLT_abc.jpg", "abc") //false
https://pythonav.com/wiki/detail/4/52/
package main
import "fmt"
func test() {
//在函数退出前,执行defer
//捕捉异常后,程序不会异常退出
defer func() {
err := recover() //内置函数,可以捕捉到函数异常
if err != nil {
//这里是打印错误,还可以进行报警处理,例如微信,邮箱通知
fmt.Println("err错误信息:", err)
}
}()
//如果没有异常捕获,直接报错panic,运行时出错
num1 := 10
num2 := 0
res := num1 / num2
fmt.Println("res结果:", res)
}
func main() {
test()
fmt.Println("如果程序没退出,就走我这里")
}
➜ test pwd
/Users/as4k/xdev/test
➜ test ls
calc.go calc_test.go
➜ test cat calc.go
package main
func add(a, b int) int {
return a + b
}
func sub(a, b int) int {
return a - b
}
➜ test cat calc_test.go
package main
import (
"testing"
)
func TestAdd(t *testing.T) {
r := add(2, 4)
if r != 6 {
t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)
}
t.Logf("test add succ")
}
➜ test go test -v
=== RUN TestAdd
calc_test.go:10: test add succ
--- PASS: TestAdd (0.00s)
PASS
ok _/Users/as4k/xdev/test 0.675s
https://pythonav.com/wiki/detail/4/53/
// I
package main
import "fmt"
//定义一个结构体数据类型
type Person struct {
Username string
Age int
Sex string
}
//表示给Person结构体,绑定添加test方法
func (p Person) test() {
fmt.Println("通过p变量,取出结构体类型中的Username值是:", p.Username)
}
func main() {
p1 := &Person{
"狗子",
18,
"男",
}
p1.test()
}
test方法和Person结构体类型绑定
test方法只能通过Person结构体的实例调用
// II
func (recevier type) methodName(参数列表)(返回值列表){}
package main
import "fmt"
//定义一个结构体数据类型
type Person struct {
Username string
Age int
Sex string
}
//此时这个(p Person)就是一个接受者
//Person结构体,人是可以说话的,添加speak方法
func (p Person) speak() {
fmt.Printf("大声的喊出了自己的名字:%v\n", p.Username)
}
//人还可以蹦跳
func (p Person) jump() {
fmt.Printf("%v:跳起来一拳打在了姚明的膝盖上\n", p.Username)
}
//人还可以进行算数
//方法的参数列表与返回值列表,与函数一致
func (p Person) getSum(n1, n2 int) int {
sum := n1 + n2
fmt.Printf("%v:飞快的计算出%d+%d的结果是%d\n", p.Username, n1, n2, sum)
return sum
}
func main() {
p1 := &Person{
"李二狗",
18,
"男",
}
p1.speak()
p1.jump()
res := p1.getSum(1, 2)
fmt.Printf("p1.getSum方法返回值是%d\n", res)
}
// III
1)结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
2)如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
3)当接受者不是一个指针时,该方法操作对应接受者的值的副本(意思就是即使你使用了指针调用函数,但是函数的接受者是值类型,所以函数内部操作还是对副本的操作,而不是指针操作
package main
import "fmt"
type People struct {
Name string
Country string
}
//此方法进行了值拷贝
func (p People) Print() {
fmt.Printf("我是谁:name=%s country=%s\n", p.Name, p.Country)
}
//此方法进行了值拷贝,不会对p1进行修改
func (p People) Set(name string, country string) {
p.Name = name
p.Country = country
}
//接收一个指针变量,可以修改原值
func (p *People) SetV2(name string, country string) {
p.Country = country
p.Name = name
}
func main() {
var p1 People = People{
Name: "二狗子",
Country: "沙河",
}
p1.Print()
//此处修改无效,并没有修改p1的原地址
p1.Set("二狗腿子", "日本")
p1.Print()
//两者效果一样,是被编译器进行了优化
//(&p1).SetV2("people02", "english")
p1.SetV2("狗官", "日本")
p1.Print()
}
https://pythonav.com/wiki/detail/4/54/
https://pythonav.com/wiki/detail/4/55/
https://www.cnblogs.com/wangyang0210/p/12986887.html
#linux
export GOOS=linux
export GOARCH=amd64
#macos
export GOOS=darwin
export GOARCH=amd64
//go:embed 入门
cat demo.go
package main
import (
_ "embed"
"fmt"
"strings"
)
var (
Version string = strings.TrimSpace(version)
//go:embed version.txt
version string
)
func main() {
fmt.Printf("Version %q\n", Version)
}
cat version.txt
v0.21
➜ embed-demo git:(master) ✗ go run demo.go
Version "v0.21"
https://taoshu.in/go/how-to-use-go-embed.html