package baseDemo
import (
"demo/baseDemo/utils"
"errors"
"fmt"
"reflect"
"testing"
)
// 单行注释
/*
多行注释
*/
// 全局变量声明
var (
num1 = 10
num2 = 20
)
// 常量声明
const Pi = 3.13
type Integer = int //类型别名
// 封装泛型
type IntNumber interface {
int | int8 | int16 | int32 | int64
}
type FloatNumber interface {
float32 | float64
}
func swapInt[T IntNumber | FloatNumber](elem1 *T, elem2 *T) {
*elem1, *elem2 = *elem2, *elem1
}
// 泛型
func swap[T int | uint64 | int32](elem1 *T, elem2 *T) {
*elem1, *elem2 = *elem2, *elem1
}
// 可变参数函数(用切片接收),无数量限制
func fun6(nums ...int) {
fmt.Println(nums)
}
func fun3(num1 int, num2 int) {
fmt.Println(num1, num2)
return
}
// 定义返回参数的名称
func fun4(num1 int, num2 int) (res1 int) {
res1 = num1 + num2
fmt.Println(num1, num2)
return
}
// 函数作为入参
func fun5(tmpFunc func(int, int)) {
num1 := 1
num2 := 2
tmpFunc(num1, num2)
fmt.Println(num1, num2)
}
func TestFun(t *testing.T) {
var float1 float64 = 3.14e-10
var float2 float64 = 3.14e+10
swapInt(&float1, &float2)
println(float1, float2)
fun6(1, 2, 3, 4)
fun5(fun3) //函数作为入参
}
// 在main方法执行前被调用,同个文件内多个init按顺序执行,多个文件根据import顺序执行init
func init() {
fmt.Println("init 1 执行")
}
func init() {
fmt.Println("init 2 执行")
}
func TestDefinition(t *testing.T) {
var float1 float64 = 3.14e-10
var float2 float64 = 3.14e+10
var char1 int = 'a' //字符对应的ASCII码值
var char2 int = '你' //中文对应的Unicode码值,需要int范围
fmt.Println(float1, float2, char1, char2)
}
func TestFor(t *testing.T) {
arr1 := [10]int{6, 8, 1, 2, 3}
num1 := 10
/**
for循环
*/
for i := range 10 {
fmt.Println(i)
}
//range字符串 字符为int32类型
//str[i] 字符为byte类型
for _, item := range "hello" {
fmt.Println(item)
}
strArr := []rune("hello")
for _, item := range strArr {
fmt.Println(item)
}
for idx, item := range arr1 {
fmt.Println(idx, item)
}
for i := 0; i < len(arr1); i++ {
}
//for循环的前置/判断/后置条件非必填
sum := 10
for sum < 1000 {
sum += sum
}
//for来实现while
for {
break
}
if arr1[0] == 0 {
}
fmt.Println(arr1, num1)
}
// 只会执行对应的case
// fallthrough 会穿透到下个case继续执行
func TestSwitch(t *testing.T) {
num1 = 2
switch num1 {
case 1:
fmt.Println("case 1")
case 2:
fmt.Println("case 2")
fallthrough
case 3:
fmt.Println("case 3")
default:
fmt.Println("case default")
}
}
// 指针使用 *(获取指针对应的值) &获取指针对应的地址
func TestPointer(t *testing.T) {
num1 := 1
var num3 *int = &num1 //num3:指向num1的指针(num1的内存地址)
num2 := &num1 //num2:指向num1的指针(num1的内存地址)
*num2 = 100 //改变指针指向的地址上的值
fmt.Println(num3)
}
// 允许多个变量同时赋值
func mySwap(num1 int, num2 int) {
num1, num2 = num2, num1
}
// defer 延迟执行(入栈(值不会随着后面改变),最后再倒序执行),不论是否报错,都会执行(用于资源释放)
func TestDefer(t *testing.T) {
fmt.Println("hello world")
defer fmt.Println("defer 1")
defer fmt.Println("defer 2")
}
func TestClassAssert(t *testing.T) {
//类型断言,需要使用interface
var num1 interface{} = 10
if v, ok := num1.(int); ok {
fmt.Printf("%d is int\n", v)
}
//断言方式2
switch num1.(type) {
case int:
fmt.Println("int")
case byte:
fmt.Println("byte")
}
}
// goto 程序跳转到标签对应位置(可读性差,尽量不用)
func TestGoto(t *testing.T) {
for i := range 10 {
for j := range 10 {
if i == 5 && j == 5 {
goto label1
}
}
}
fmt.Printf("-------------")
label1:
}
// 匿名函数使用
func TestAnonymousFun(t *testing.T) {
//直接执行匿名函数
res := func(num1 int, num2 int) int {
return num1 + num2
}(10, 11)
//讲匿名函数赋值给一个对象,然后通过对象执行(用的少)
sum := func(num1 int, num2 int) int {
return num1 + num2
}
res1 := sum(10, 20)
res2 := sum(10, 20)
fmt.Println(res, res1, res2)
}
// 异常捕获(defer + recover:获取error)
func TestErrorCatch(t *testing.T) {
defer func() {
err := recover()
if err != nil {
fmt.Println("错误被捕获")
}
}()
num1 := int(0)
num1 = 10
res := 10 / num1
scanf, err := fmt.Scanf("%s", &res)
if err != nil {
panic("出现错误") //panic错误处理
} //按照固定格式输入
fmt.Println(res, scanf)
}
// 自定义错误返回
func returnError() (err error) {
num1 := 0
if num1 == 0 {
return errors.New("除数不能为0")
} else {
return nil
}
}
// 反射
func TestReflect1(t *testing.T) {
interfaceEmptyFun(10)
interfaceEmptyFun("hello world")
interfaceEmptyFun(utils.Point{1, 1})
}
func interfaceEmptyFun(input interface{}) {
inputType := reflect.TypeOf(input) //反射获取对象的类型(具体的结构体名称)
value := reflect.ValueOf(input) //反射获取对象的值
kind := value.Kind() //反射获取对象的类别(struct, string int)
if inputType.String() == "int" { //同意type判断类型
tmp := value.Int()
//value.Elem().SetUint(1234) //反射修改基本数据类型的值
fmt.Println(tmp)
}
tmpValue1 := value.Interface() //将value转为接口类型,用于类型断言
value1, flag := tmpValue1.(utils.Point) //通过类型断言判断类型
if flag == true {
//numMethod := value.Elem().NumMethod()
//numField := value.Elem().NumField()
//value.Elem().FieldByName("x").SetInt(10)
//value.MethodByName("print") //通过方法名反射调用方法
//value.Method(1).Call(nil) //反射调用方法,方法首字母药大写,顺序按照首字母ascll码排序
fmt.Println("是point类型", value1)
//fmt.Println(numField, numMethod)
}
fmt.Println(inputType, value, kind)
}
go-基础学习(持续更新)
于 2024-04-21 01:30:45 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)