韩国设计公司网站,网站建设的基本步骤,房山建设网站,网站用ps做还是aiGo学习-Day10
个人博客#xff1a;CSDN博客
反射 编写函数适配器#xff0c;序列化和反序列话可以用到 反射可以在运行时#xff0c;动态获取变量的各种信息#xff0c;例如类型#xff0c;结构体本身的信息#xff0c;修改变量的值#xff0c;调用关联的方法 反射是…Go学习-Day10
个人博客CSDN博客
反射 编写函数适配器序列化和反序列话可以用到 反射可以在运行时动态获取变量的各种信息例如类型结构体本身的信息修改变量的值调用关联的方法 反射是不是和映射相反是一种逆函数 变量到空接口相互转换空接口和reflect.value相互转换 动手一下 import (fmtreflect
)func test(a interface{}) {b : reflect.TypeOf(a)fmt.Println(b)
}func main() {var a int 10test(a)
}打印 “int” reflect.TypeOf()//从接口获取原类型
reflect.ValueOf()//从接口获取reflect.Value类型.Int能取到具体的类型
//如果需要原类型需要类型断言
reflect.Interface//把reflect.Value转换成空接口Kind是大的种类Type是小的类型 常量在定义的时候必须初始化 reflect.Value.Kind返回的是常量 如果传入指针类型的话反射常常需要改变原来的值指针类型需要.Elem方法取到值再用.SetInt之类的方修改原来的值 Value//指reflect.Value
Value.NumField()//获取字段数
Value.Field()//根据下标获取第几个字段,返回的也是relect.Value
Tpye//指reflect.Type
Tpye.Field().Tag.Get(key)//可以获取tag键值是结构体里面设置的例如json:的key就是json,序列化反序列化的键值固定取json其实可以自定义
Value.NumMethod()//获取方法数
Value.Method().Call(...)//获取第几个方法然后调用
//这个顺序是按照函数名字典序排列的Call传的是Value切片返回的也是Value切片
//输入的时候需要定义一个Value切片用reflect.ValueOf(xx)插入这个切片
Value.Elem().Field().SetXxx//修改字段
...FieldByName()//可以用字段名来找
Value.New()//为指针申请空间可以通过反射来创建类型网络编程
Golang的主要设计目标之一就是面向大规模的后端服务程序网络通信是服务端程序必不可少的一部分网络编程有两种 TCPTransmission Control Protocol socket编程和HTTP编程建立在前者之上做服务器尽量少开端口一个端口只能被一个程序监听
监听端口小Demo net包提供了可以指的I/O接口 package mainimport (fmtnet
)func main() {fmt.Println(开始监听)//使用tcp协议监听本机listen, err : net.Listen(tcp, 0.0.0.0:8888)if err ! nil {fmt.Println(err, err)}//延迟关闭defer listen.Close()//循环等待for {//等待客户端连接fmt.Println(等待连接...)//获取连接conn, err : listen.Accept()if err ! nil {fmt.Println(err, err)} else {fmt.Println(con, conn)}//起一个协程为客户端服务}
} 用telnet呼叫一下 telnet 127.0.0.1 8888 开始监听
等待连接...
con {{0xc00010ec80}}
等待连接...
//返回客户端 conn, err : net.Dial(tcp, ip...:端口)
//获取连接
//Dial是拨号的意思通过端口就能和对应的程序进行交流 func main() {conn, err : net.Dial(tcp, 127.0.0.1:8888)if err ! nil {fmt.Println(err, err)}fmt.Println(连接成功conn, conn)
}
//注意此时要开着上面的监听程序
//输出 连接成功conn {{0xc00010ca00}}
发送接收
server.go
package mainimport (fmtnet
)func process(conn net.Conn) {//连接过多不关闭的话就会导致其他连接无法成功defer conn.Close()for {buf : make([]byte, 512)//如果没有Write会停在这里类似我们stdin输入的时候光标会停在输入的位置//如果连接突然中断的话这里会报错//TCP底层会定时发送消息检查连接是否存在n, err : conn.Read(buf)if err ! nil {fmt.Println(err, err)return//有可能是关闭了}//字节切片要强制转换//buf后面的存的可能是乱七八糟的东西注意取前n个fmt.Print(string(buf[:n]))}
}func main() {fmt.Println(开始监听)//使用tcp协议监听本机listen, err : net.Listen(tcp, 0.0.0.0:8888)if err ! nil {fmt.Println(err, err)}//延迟关闭defer listen.Close()//循环等待for {//等待客户端连接fmt.Println(等待连接...)//获取连接conn, err : listen.Accept()if err ! nil {fmt.Println(err, err)} else {fmt.Println(con, conn)}//起一个协程为客户端服务go process(conn)}
}
client.go
package mainimport (bufiofmtnetos
)func main() {conn, err : net.Dial(tcp, 127.0.0.1:8888)if err ! nil {fmt.Println(err, err)}fmt.Println(连接成功conn, conn)//创建标准stdin的readerreader : bufio.NewReader(os.Stdin)//读取一行str, err : reader.ReadString(\n)if err ! nil {fmt.Println(err, err)}n, err : conn.Write([]byte(str))if err ! nil {fmt.Println(err, err)}fmt.Println(发送了n个字节n, n)
}
一个小点发送的字节数多2应该是回车键的缘故可能这里是当成\n\r