go-基础学习(持续更新)

本文详细介绍了Go语言中的包结构、变量声明、常量、泛型、类型别名、可变参数函数、函数作为入参、测试用例、错误捕获、自定义错误返回以及反射的基本操作。
摘要由CSDN通过智能技术生成
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)
}

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值