GO编程 利用interface传参(正向/反向)

问题:
一个函数  调用它的时候 参数的传入 可能是string也可能是[]byte

那么它该怎么处理?

案例

func tx(ws_conn WS_CONN, text string) error {

    ws_conn.Lock.Lock()
    defer ws_conn.Lock.Unlock()
    return ws_conn.C.WriteMessage(1, []byte(text)) //1-websocket.TextMessage 写死
}

那么它的调用是
tx(Wsm.WS_CONN, "hello")
假设参数2是[]byte 要调用怎么办??

简单妥协的方式是 传参的时候强转一下 类似如下
func tx(ws_conn WS_CONN, b []byte) error {

    ws_conn.Lock.Lock()
    defer ws_conn.Lock.Unlock()
    return ws_conn.C.WriteMessage(1, b
}
它的调用是 这样也可以
tx(Wsm.WS_CONN, []byte("hello"))

高级一点 能不能统一?
https://studygolang.com/articles/7462
接口的转换遵循以下规则:

1.普通类型向接口类型的转换是隐式的。

2.接口类型向普通类型转换需要类型断言。

tx(Wsm.WS_CONN, []byte("hello"))
func tx(ws_conn WS_CONN, i interface{}) error {

    var t []byte
    ws_conn.Lock.Lock()
    defer ws_conn.Lock.Unlock()
    if value, ok := i.(string); ok {
        fmt.Printf("i is a string and its value is %s\n", value)
        t = []byte(value)
    } else if value, ok := i.([]byte); ok {
        fmt.Printf("i is a []byte and its value is %s\n", string(value))
        t = value
    }

    return ws_conn.C.WriteMessage(1, t) //1-websocket.TextMessage 写死
}

随意直接调用了

小结:在函数内部用

func tx(ws_conn WS_CONN, i interface{}
    if value, ok := i.(string)

问题2:

一个函数 需要传入的参数是 接口!

这样的话 别人使用的时候 很方便 随便丢

但是我自己麻烦了!!!我不知别人给我的  我怎么还回去

golang interface{}转换成struct结构体的两种方法_qq_26372385的博客-CSDN博客_golang interface 转struct

2个办法

func SET_GW_DEFAULT_CTRL_CMD_RX(param interface{}) {

    pack, ok := (param).(PACK_DATA)

   if ok {

        pack_len := *(*uint16)(unsafe.Pointer(&(pack.Data_len)))

结论:

1-除了内置的数据类型外,都推荐使用接口的方法来传递相关方法

2-名称.(type)用于类型查询,名称.(具体类型)用于类型转换。因此,使用接口作为函数参数是很有价值的。

案例

package main

import (
	"fmt"
)



func printAnyValue(args ...interface{}) {
	//使用for range方法获取每一个接口
	for _, arg := range args {
		//使用.(type)方法查询接口的数据类型
		switch arg.(type) {
		case int:
			fmt.Println("the type is int")
			v := arg.(int)
			fmt.Println(v)
		case string:
			fmt.Println("the type is string")
			v := arg.(string)
			fmt.Println(v)
		}
	}
}

func main() {
	var V1 int = 8
	var V2 string = "123"

	printAnyValue(V1)
	printAnyValue(V2)
	printAnyValue(V2, V1, V2, V1)
}

【注意一下最后的测试 它这个是不是就是zerolog的链式调用了?也即是参数一骨碌丢进去 先丢的谁 谁就先执行】

[Running] go run "c:\Users\Koson.Gong\Desktop\sgo\main.go"

the type is int

8

the type is string

123

the type is string

123

the type is int

8

the type is string

123

the type is int

8

[Done] exited with code=0 in 1.776 seconds


所以可以改进做开始的代码了

func tx(ws_conn WS_CONN, b bool, args ...interface{}) error {
	/*
	好像[]byte只有第一个INFO再发 而且它是不要B64
	其他消息都是string 需要B64
	*/
	var t []byte
	ws_conn.Lock.Lock()
	defer ws_conn.Lock.Unlock()

	for _, arg := range args {
		//使用.(type)方法查询接口的数据类型
		switch arg.(type) {
		case string:
			t = []byte(arg.(string))
			fmt.Printf("i is a string and its value is %s\n", string(t))

		case []byte:
			t = arg.([]byte)
			fmt.Printf("i is a []byte and its value is %s\n", string(t))
		}

	}

这里是:

        case string:

            t = []byte(arg.(string))

强转string为[]byte  同时string的获得是arg的回转

继续优化  下面不错了

assigning the result of this type assertion to a variable could eliminate the followin assertion解决_djqueue的博客-CSDN博客

func tx(ws_conn WS_CONN, b bool, args ...interface{}) error {
	/*
		好像[]byte只有第一个INFO再发 而且它是不要B64
		其他消息都是string 需要B64
	*/
	var t []byte
	ws_conn.Lock.Lock()
	defer ws_conn.Lock.Unlock()

	for _, arg := range args {
		//使用.(type)方法查询接口的数据类型
		//并且马上转出来
		switch arg := arg.(type) {
		case string:
			t = []byte(arg) //arg已经就是string
			fmt.Printf("i is a string and its value is %s\n", string(t))

		case []byte:
			t = arg //arg已经就是[]byte
			fmt.Printf("i is a []byte and its value is %s\n", string(t))
		}

	}

++++++++++

反过来 接口里面 发消息

package main

import (
	"fmt"
	"time"
)

/*
& 编程任务:通道和interface结合使用
& 1-通道利用结构体封装一次
*/
type PACK_DATA struct {
	Value chan bool
}

/*
& 2-利用. 可以发消息出去了!
*/
func BLE_NODE_STATE_CODE_RX(param interface{}) bool {
	pack, ok := (param).(PACK_DATA)
	if !ok {
		return false
	}
	fmt.Println(pack)
	pack.Value <- true
	return true
}

func main() {

	var Blem = PACK_DATA{
		Value: make(chan bool, 1),
	}

	go func() {
		time.Sleep(time.Second * 2)
		BLE_NODE_STATE_CODE_RX(Blem)
	}()

	o := make(chan bool)
	go func() {
		for {
			select {
			case v := <-Blem.Value:
				fmt.Println(v)
			case <-time.After(5 * time.Second):
				fmt.Println("timeout")
				o <- true
				return
			}
		}
	}()

	<-o
	fmt.Println("程序结束")
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值