问题:
一个函数 调用它的时候 参数的传入 可能是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的回转
继续优化 下面不错了
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("程序结束")
}