一.demo

1 单包程序运行

package main //注意要有src目录?
//F:\Program Files\go\goprojects\src\project1\main包\main.go

import "fmt"

func main() {
	s1 := "[1]建议换行符号'\\r\\n' windows='\\n' linux='\\r\\n'\n\r"
	s2 := "go run main.go\t\tgo build main.go\tmain.exe\r\n"
	s3 := "gofmt main.go\t\tgofmt -w main.go"
	fmt.Println(s1, s2, s3)

	var str1 string = "\r\n[vscode]\r\nshiftAlt上下箭头=复制当前行\r\n"
	var str2 = "CtrlShiftK=删除当前行+下一行变成当前行\r\n"
	str3 := "CtrlShiftEnter=上面新增1行\r\n"
	str4 := "某行首字符前面 点击键盘Tab shiftTab=缩进代码\n"
	fmt.Printf("%s%s%s%v", str1, str2, str3, str4)
	fmt.Print("vscode_File(Edit)有快捷键提示\n\r")
}

/*shiftAltA=选中需要添加或者取消多行注释 ctrl/=该行 添加或取消单行注释 
Vscode_File_prefence_setting 搜索框  
1  Files: Auto Save  =onFocusChange 自动保存
2  editor.fontSize    =19  editor.fontWeight 默认"normal"
3  extension.autoUpdate  =false(None) //取消扩展自动更新 以后无通知
4  Update: Enable Windows Background Updates //启用后台更新可以取消
5  editor.quickSuggestions //建议提示 需要配套扩展插件使用
*/

2 多包的主程序运行

package utils //推荐习惯(包名=当前目录名一致)不一致也可以但不推荐
//F:\Program Files\go\goprojects\src\project1\utils包\utils.go
//注意需要src目录
import (
	"fmt"
)

func Cal(n1 float64, n2 float64, operator byte) float64 {
	//注意 函数名称首字母大写=public 小写=private
	var res float64
	switch operator {
	case '+':
		res = n1 + n2
	case '-':
		res = n1 - n2
	case '*':
		res = n1 * n2
	case '/':
		res = n1 / n2
	default:
		fmt.Println("操作符号错误...")
	}
	return res
}
package main

//F:\Program Files\go\goprojects\src\project1\main包目录\main.go
//注意有src目录?
import (
	"fmt"
	"project1/utils" //出现错误?
)

func main() {
	fmt.Printf("【1】%v\t【2】%v\n", cal(3, 4, '+'), cal(2.2, 1.1, '-'))
	fmt.Printf("【3】%v %v\n", utils.Cal(3, 4, '/'), utils.Cal(3, 4, '*'))

}
func cal(n1 float64, n2 float64, operator byte) float64 {
	var res float64
	switch operator {
	case '+':
		res = n1 + n2
	case '-':
		res = n1 - n2
	case '*':
		res = n1 * n2
	case '/':
		res = n1 / n2
	default:
		fmt.Println("操作符号错误...")
	}
	return res
}

/*
【多个包的程序运行】
1.配置环境变量 GOPATH=F:\Program Files\go\goprojects
2.vscode配置GOPATH File_preference_setting输入go.gopath修改后重启vscode
3.Gopath路径下cmd
  go env -w  GO111MODULE=off
  go build -o bin/my.exe project1/main (进入bin目录运行 my.exet程序)
4.也可以直接运行vscode的main.go代码
*/

3 数据类型1

package main

import (
	"fmt"
	"math"
	"unsafe" //unsafe.Sizeof该方法可以求出对象的字节长度
)

var (
	pl, pf = fmt.Println, fmt.Printf
)

func main() { f8() }

func f1() {
	var j0 int8 //有符号int8 1字节范围=-128~127 声明未赋值=0
	var j1, j2 int8 = -128, 127
	pl("【1】", j0, j1, j2) //右边int字面类型根据左边调整为int8

	var i0, i1, i2, i3, i4 uint8 = byte(0), 255, 'a', 'A', '0'
	pl("【2】", i0, i1, i2, i3, i4, "\t无符号int8=0~256")

	var b0, b1, b2, b3 byte = 0, byte(255), 'a', 'z'
	b4, b5, b6, b7 := 'A', 'Z', '0', '9'
	pl("【3】", b0, b1, b2, b3, b4, b5, b6, b7, "byte=uint8")
	pf("【4】(%T %T %T) (%p %p %p)\n", j0, i0, b0, &b0, &b1, &b2)

	pl(unsafe.Sizeof(j0), unsafe.Sizeof(i0), unsafe.Sizeof(b0))
	/* shiftAltA vscode可直接识别下面代码错误 暂未找到方法忽略错误
	fmt.Println(uint8(-1), uint8(256), int8(-129), int8(128))
	*/
}
func f2() { //占2个字节 vscode=CtrlS保存后运行程序
	var i1, i2, i3 uint16 = 0, uint16(math.Exp2(16) - 1), 65535
	fmt.Println("【1】", i1, i2, i3, "使用强制类型转换")
	pf("【2】%T (%p %v %x %p)\n", i1, &i1, &i2, &i3, &i3)
	var j1, j2 = int16(-math.Exp2(15)), int16(math.Exp2(15) - 1)
	var j3, j4 int16 = -32768, 32767

	pl("【3】")
	pf("(%T %p %x %v) 强制类型转换\r\n", j1, &j1, j1, j1)
	pf("(%T %p %x %v %d)\r\n", j2, &j2, j2, j2, j2)
	pf("(%T %p %x %v)\r\n", j3, &j3, j3, j3)
	pf("(%T %p %x %v)\r\n", j4, &j4, j4, j4)
}
func f3() { //占4个字节 rune是int32别名 byte是uint8别名
	var i1, i2 uint32 = 0, uint32(math.Exp2(32) - 1)
	pf("i=(%v %d %T %p) i2=(%p %v)\n", i1, i1, i1, &i1, &i2, i2)
	j1, j2 := int32(-math.Exp2(31)), int32(math.Exp2(31)-1)
	pl(&j1, &j2, j1, j2)
}
func f4() { //占8字节
	var m64, m63, m62 float64 = math.Exp2(64), math.Exp2(63), math.Exp2(62)
	fmt.Printf("%T %v %v %v\n", m64, m64, m63, m62)
	pf("%v %v %v %v\n", uint64(m64), uint64(m63), uint64(m62)*2)

	var arr [4]uint64 = [4]uint64{0, 2*uint64(m63) - 1}
	pl(arr, &(arr[1]), &(arr[0]))

	arr2 := [...]int64{int64(-m63), int64(int64(m63) - 1)}
	pl(arr2, &(arr2[1]), &(arr2[0]), "相差8字节")
}
func f5() {
	var i0 int
	i1, i2 := 100, 200
	var i3 int
	i3 = 300
	pl(i0, i1, i2, i3, &i0, &i1, &i2, &i3)
	pf("%T %T %T %T %T\r\n", math.Exp2(2), 4, int8(4), byte(4), uint8(4))
	pf("%T %T %T %T\r\n", int16(4), int32(4), rune(4), int64(4))
}

func f6() {
	var v1 int
	var v2 float32
	var v3 float64
	var v4 bool
	var v5 string
	var v6 byte = 'a'

	pf("【1】%d %f %.2f %t %s空串 %c\n", v1, v2, v3, v4, v5, v6)
	pf("【1】%v %v %v %v %v空串 %v\n", v1, v2, v3, v4, v5, v6)
	pf("【1】%x %x %x %x %x空串 %x\n", v1, v2, v3, v4, v5, v6)
	pf("【1】%x %x %x %x %x %x\n", &v1, &v2, &v3, &v4, &v5, &v6)
	fmt.Print("【2】", unsafe.Sizeof(v1), unsafe.Sizeof(v2), unsafe.Sizeof(v3), "\t")
	fmt.Println(unsafe.Sizeof(v4), unsafe.Sizeof(v5), unsafe.Sizeof(byte(200)))

	var n1, price = 100, 99.99
	fmt.Printf("【3】100默认%T-字节数%d 99.99默认=%T\n", n1, unsafe.Sizeof(n1), price)
	f1, f2, f3, f4, f5 := 0.123, 0.01234567890123456789, 9e+5, 9e+6, 9e7
	fmt.Println("【4】", f1, f2, f3, f4, f5)
}

func f7() { //1 高类型(强)转低 溢出处理不报错 右边立即数是int64类型 自动根据左边转换
	var i int32 = 100
	fmt.Printf("【1】(%T %v) (%T %v)\n", i, i, int8(i), int8(i))
	var j = math.Exp2(15) - 1
	fmt.Printf("【2】[%T %v] [%T %v]\n", j, j, int8(j), int8(j))

	//2 低类型转化为高(低精度转高) 其它语言会自动转化
	var f float32 = float32(i)
	fmt.Printf("%T %v \n", f, f)
}

func f8() { //必须是相同类型才能相加 其它语言会自动转化高类型
	var i int64 = 10
	var j int32 = 20         //i+j会报错 一定声明强转  i+int64(j) 或者int32(i)+j
	x := int64(i) + int64(j) //相加结果如果超出范围 按照溢出处理
	y := int8(i) + 127       //如果加128 则报错? 自动转化低类型
	fmt.Println(i, j, x)
	fmt.Printf("%T %v", y, y)
}

3 数据类型2

package main

import (
	"fmt"
	_ "math"
	"strconv"
	"unsafe"
)

func main() { g1() }

func f1() { //【字符】
	var i1, i2, i3, i4 uint8 = 'a', 'z', 'A', 'Z'
	i5, i6 := '0', '9'
	fmt.Printf("%T %d %c\t", i1, unsafe.Sizeof(i1), 'a'+10)
	fmt.Println(i1, i2, i3, i4, i5, i6, 'a'+10)

	var c1, c2, c3, c4, c5, c6 byte = 'a', 'z', 'A', 'Z', '0', '9'
	fmt.Printf("%T %d\t", i1, unsafe.Sizeof(c1))
	fmt.Println(c1, c2, c3, c4, c5, c6)

	var C1, C2 int = '中', '国'
	fmt.Println(C1, C2, 'a'+10)
	fmt.Printf("%c  (%T %c %v)\n", C1, C2, C2, C2)
}
func f2() { //【字符串】长度为什么都是16?
	var a string = "【1】统一UT8编码\n一旦赋值不可变\t" +
		"address[0]=\"a\"错误\n"
	fmt.Printf("%s %T %d %p %d\n", a, a, unsafe.Sizeof(a), &a, len(a))
	code := `【2】
    使用反引号=在Tab键上方的符号\n 批量输入多行\t字符串
    `
	fmt.Printf("%s\n%T\n", code, code)
	fmt.Printf("%d %p %d\n", unsafe.Sizeof(code), &code, len(code))
	var str = "abc"
	fmt.Printf("%s %v %T\n", str, str, str)
	fmt.Printf("%v %p %v\n", unsafe.Sizeof(str), &str, len(str))

	arr := [...]string{"abc", "def", "ghi"}
	fmt.Println(arr, &(arr[0]), &(arr[1]), &(arr[2]))
	fmt.Printf("%T %p\n", &(arr[1]), &(arr[1]))
	fmt.Printf("%T %p\n", &arr[1], &arr[1])

	fmt.Println(fmt.Sprintf("%d", &arr[0]))
	fmt.Println(fmt.Sprintf("%d", &arr[1]))
	fmt.Println(fmt.Sprintf("%d", &arr[2]))

	s := fmt.Sprintf("%d", &arr[2])
	i1, err1 := strconv.Atoi(s)
	i2, err2 := strconv.ParseInt(s, 10, 64) //0八进制 10 16
	fmt.Printf("%T %T %v (%v %v)\n", s, i1, err1, i2, err2)
}

func f3() { //【fmt.Sprintf】
	num1, num2 := int(99), float64(23.456)
	var s1, s2 string = fmt.Sprintf("%d", num1), fmt.Sprintf("%f", num2)
	fmt.Printf("【1】%T: %v %q \n", s1, s1, s1) //%q=带双引号"值"
	fmt.Printf("【2】%T: %v %q \n", s2, s2, s2)
	fmt.Println("【3】", fmt.Sprintf("布尔(\"%t\")", true))
	fmt.Println("【4】", fmt.Sprintf("%c", 'm'))
}
func f4() { //【strconv.FormatInt FormatFloat Itoa FormatBool】
	s1 := strconv.FormatInt(int64(99), 10)
	s2 := strconv.FormatFloat(23.456, 'f', 10, 64)
	fmt.Printf("【1】(%T %v %q) (%T %v %q)\n", s1, s1, s1, s2, s2, s2)
	fmt.Printf("【2】%q %T\n", strconv.Itoa(99), strconv.Itoa(99))
	s3 := strconv.FormatBool(true)
	fmt.Printf("【3】%T %v", s3, s3)
}
func g1() {
	var s1, s2, s3, s4 = "true", "123456", "123.456", "hello"

	var b bool
	var n1 int64
	var n2 int
	var f1 float64
	var f2 float32
	b, _ = strconv.ParseBool(s1)
	n1, _ = strconv.ParseInt(s2, 10, 64)
	n2 = int(n1)
	f1, _ = strconv.ParseFloat(s3, 64)
	f2 = float32(f1)

	fmt.Printf("%T:%v \t %T:%v \t %T:%v\n", b, b, n1, n1, n2, n2)
	fmt.Printf("%T:%v \t %T:%v\n", f1, f1, f2, f2)

	E1, e := strconv.ParseInt(s4, 10, 64)
	fmt.Printf("%s %T:%v [err]%v\n", s4, E1, E1, e)
	bool_value, e := strconv.ParseBool(s4)
	fmt.Println(bool_value, e) //异常已经写在方法本身之中

}

4 运算

package main

import (
	"fmt"
	_ "math"
	_ "strconv"
	_ "unsafe"
)

func main() { z2() }

func f1() {
	var v0, v1 int
	v1 = 1
	var v2 int = 2
	var v3 = 10.11
	v4 := "Tom"
	fmt.Println(v0, v1, v2, v3, "\n两串相加拼接=", v4+"tom")
}

func f2() {
	var n1, n2, n3 int
	n1, n2, n3 = 11, 12, 13
	fmt.Println("\"int n1 n2 n3=\"", n1, n2, n3)

	var p1, p2, p3 = 21, "zhangsan", 10.11
	s1, s2, s3 := 31, "32aa", 33.33
	fmt.Println(p1, p2, p3, "\t", s1, s2, s3)
}

func f3() {
	sum, sub := getVal(30, 20)
	fmt.Println("sum=", sum, "sub", sub)
	sum2, _ := getVal(100, 50)
	fmt.Println("sum2=", sum2)
}
func getVal(num1 int, num2 int) (int, int) {
	sum := num1 + num2
	sub := num1 - num2
	return sum, sub
}

func f4() { //值类型=常量变量直接存储值通常在内存栈中分配
	var i int = 100   //引用类型=指针 slice切片 map 管道chan interface等
	var ptr *int = &i //引用类型 通常在内存堆分配空间
	fmt.Printf("i地址:%v i值:%d\n", &i, i)
	fmt.Printf("ptr=%v ptr地址=%v ptr指向值=%v\n", ptr, &ptr, *ptr)
}

func g1() { //1.算式运算符 +-=正号负号加减/字符相加拼接 */% ++ --
	fmt.Println(10/3, 10%3, -10/3, -10%3, 10.0/4, "取余公式=", 10-(10/3)*3)
	var i int = 10
	var j int = 10
	i++ //报错 var a int = i++ 或 j--; i++ j--只能独立使用; 没有++i
	j-- //报错 if i++>0 {};设计理念减少歧义; 没有--j
	var a, b int = i, j
	fmt.Println(i, j, a, b)
}

func g2() { //2.比较运算符/关系运算符 返回值bool类型
	var n1 int = 9
	var n2 int = 8
	fmt.Println(n1 == n2, n1 != n2, n1 > n2, n1 >= n2, n1 < n2, n1 <= n2)
}

func g3() { //3.逻辑
	var age int = 40
	if age >= 30 && age <= 50 {
		fmt.Println("ok1:", age >= 30 && age <= 50)
	}
	fmt.Println(age > 60 || age < 18, !(age > 30))
	fmt.Println("[短路与false]", age > 50 && age < 60)
	fmt.Println("[短路与true]", age > 30 || age < 10)
}

func z1() {
	var i, j, k, l int = 5, 011, 0x11, 0x11
	fmt.Println(i, j, k, l)

	fmt.Printf("i=[%b,%o,%d,%x]\t", i, i, i, i) //%t=bool值
	fmt.Printf("j=[%b,%o,%d,%X]\n", j, j, j, j)

	var a1, a2 int = 1 >> 2, 1 << 2 //右移两位相当于整除2 左移两位乘4(除了高位溢出)
	fmt.Println(a1, a2)             //右移高位补符号 左移后补0

	var b1 int = -1 >> 2 //正整数=原码=补码 负整数补码=正整原码取反+1
	var b2 int = -1 << 2 //左移2位=1100 真值=-(取反0011+1=0100)=-4
	fmt.Println(b1, b2)  //-1补=1111右移不变

	fmt.Println(2&3, 2|3, 2^3, "\t", 0b010&0b011, 0b010|0b011, 0b010^0b011)

}

func z2() { //6.其它 如*取(地址)指向值 &取(常量变量的)地址
	var n string
	var age byte
	var salary float32
	var isPass bool
	fmt.Printf("请输入姓名: ")
	fmt.Scanln(&n) //中断执行
	fmt.Printf("年龄: ")
	fmt.Scanln(&age)
	fmt.Printf("薪水: ")
	fmt.Scanln(&salary)
	fmt.Printf("是否全职: ")
	fmt.Scanln(&isPass)
	fmt.Printf("姓名:%v 年龄:%v 薪水:%v 全职:%v\n", n, age, salary, isPass)

	fmt.Printf("请输姓名,年龄,薪水,是否通过考试,以空格隔开: ")
	fmt.Scanf("%s %d %f %t\n", &n, &age, &salary, &isPass)
	fmt.Printf("姓名:%v 年龄:%v 薪水:%v 全职:%v\n", n, age, salary, isPass)
}