Go语言的变量、函数、Socks5代理服务器
2019独角兽企业重金招聘Python工程师标准>>>
Go语言中变量的声明和JavaScript很像,使用var关键字,变量的声明、定义有好几种形式
1. 变量和常量
// 声明并初始化一个变量
var m int = 10
// 声明初始化多个变量
var i, j, k = 1, 2, 3
// 多个变量的声明(注意小括号的使用)
var(
no int
name string
)
// 声明时不指明类型,通过初始化值来推导
var b = true // bool型
// := 隐含声明变量并赋值
str := "mimvp.com" // 等价于var str string = "mimvp.com"
Go 语言中 = 和 := 有什么区别?
= 是赋值, := 是声明变量并赋值
// = 使用必须使用先var声明例如: var a a = 100// 或 var b = 100// 或 var c int = 100// := 是声明并赋值,并且系统自动推断类型,不需要var关键字 d := 100
// Go中有一个特殊的变量下划线"_" 表示任何赋给它的值将被丢弃
_, Ret:= 2, 3 // 2赋值被丢弃
Go语言的编译器,对声明却未使用的变量在报错,因此变量声明了就必须使用,如果要使用变量也必须先声明
Go语言和C语言一样,Go语言中也是使用分号来终结语句。但是和C语言不同的是,Go语言的词法分析器在扫描源代码的过程中使用简单的规则自动插入分号,因此在编写源代码的多数时候就不需要加分号了
Go语言词法分析器插入分号的规则:如果在一个新行前方的最后一个标记是一个标识符(包括像int和float64这样的单词)、一个基本的如数值这样的文字、或以下标记中的一个时,会自动插入分号
Go语言通常仅在for语句中使用分号,以此来分开初始化器、添加和增量。还有一种情况就是当你在一行中写了多个语句,也需要使用分号来分开
由于Go语言词法分析器添加分号的特殊性,所以在有些情况下需要注意:
你都不应该将一个控制结构(if、for、switch或select)的左大括号放在下一行。
如果这样做,将会在大括号的前方插入一个分号,这可能导致出现不想要的结果。
常量:在程序不能被改变的值,一般都定义为数值,布尔值,字符串等
格式:const constName [type] = val
1). var num = 3 // 实际上 3 也称为常量
2). 格式中 val 可以是表达式,但不能为运行时才能知道结果的表达式
3). 预定义常量: true / false / iota
4). 定义多个常量时,也可用下面方式
const ( constName1 [type] = val1 constName2 [type] = val2 )
示例代码:
/** * mimvp.com * 2017.1.20 */// 声明当前文件所属的包名,main是一个可独立运行的包,编译后会生成可执行文件 package main import "fmt" // 导入包 var id = 123456 /* id2 := 654321 // 在函数外用 := ,编译时会出现错误,局部变量声明应在函数内部 // non-declaration statement outside function body */ const PI = 3.14 // 常量声明// 每个可独立运行的程序,都包含入口函数 main ,与其他语言相同,但无参数和返回值 func main() { var num int num = 100 fmt.Println(num) // 输出 100 var num1, num2 int num1, num2 = 1, 2 fmt.Println(num1, num2) // 输出 1 2 var no1, no2 = 3, 4 fmt.Println(no1, no2) // 输出 3 4 n1, n2 := 5, 6 fmt.Println(n1, n2) // 输出 5 6 _, n := 7, 8 fmt.Println(n) // 输出 8 var ( key1 string key2 string ) key1, key2 = "k1", "k2" fmt.Println(key1, key2) // 输出 k1 k2 var ( a = 9 b = 10 ) fmt.Println(a, b) // 输出 9 10 fmt.Println(id) // 输出 123456 fmt.Println(PI) // 输出 3.14 /* PI = 3.1415 // 改变常量的值,编译会出现错误 // cannot assign to PI // cannot use 3.1415 (type float64) as type ideal in assignment */ }
2. 函数使用
1)Go语言函数格式
func GetMsg(i int) (str string) {fmt.Println(i)str = "hello mimvp.com"return str }
解释说明:
func 说明这是个函数
GetMsg是函数名
(i int) 函数接收一个int参数,是传入参数
(str string) 函数返回一个string类型返回值,是返回参数
2)Go语言函数可返回多个值
函数返回多个值,跟Java、PHP、C等主流语言都不一样,但和Python、lua等脚本语言是一样的
vim mimvp_func.go
func GetMsg(i int) (str string, err string) {fmt.Println(i)str = "hello mimvp.com"err = "no err"return str, err }func main() {fmt.Println(GetMsg(100)) }
编译执行:
$ go build mimvp_func.go
$ ./mimvp_func
100
hello mimvp.com no err
3)defer的使用
defer的意思是"在函数退出时调用",特别用于对文件进行读写操作的时候,需要在open之后要调用close操作,将close操作使用defer
func ReadFile(filePath string)(){file.Open(filePath)defer file.Close()if true {file.Read()} else {return false} }
上述代码含义是在file.Open后不立即调用close,当return false的时候调用file.Close(),这样就有效避免了C语言中的内存泄露问题。
4)理解 panic,recover
上面讲述了很多变量和函数,还没介绍 throw - try - catch 的用法
Go语言里,Panic和Recover就是其他语言中的throw和catch
示例代码:
package mainimport "fmt"func main() {f()fmt.Println("Returned normally from f.") }func f() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered in f", r)}}()fmt.Println("Calling g.")g(0)fmt.Println("Returned normally from g.") }func g(i int) {if i > 3 {fmt.Println("Panicking!")panic(fmt.Sprintf("%v", i))}defer fmt.Println("Defer in g", i)fmt.Println("Printing in g", i)g(i + 1) }
运行结果:
$ ./mimvp-try-catch
Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
Recovered in f 4
Returned normally from f.
Panic抛出了信息,并且跳出函数。Recover接受到了信息,并且继续处理。
这个例子理解了基本就掌握了Recover和Panic
3. Socks5代理服务器
package mainimport ("net""fmt""io""bytes""encoding/binary" )type Methods struct{ver, nmethods uint8methods uint8 }type sock5cmd struct{ver, cmd, rsv, atyp uint8dst [255]uint8 }type proxyCoder struct {conn net.Conn }func (c *proxyCoder) readMethods() Methods {var m Methodsb := make([]byte, 1024)n, err := c.conn.Read(b)if err != nil && err != io.EOF { panic(err) }buf := bytes.NewBuffer(b[0:n])err = binary.Read(buf, binary.LittleEndian, &m.ver)if err != nil {fmt.Println("binary.Read failed:", err)}err = binary.Read(buf, binary.LittleEndian, &m.nmethods)if err != nil {fmt.Println("binary.Read failed:", err)}err = binary.Read(buf, binary.BigEndian, &m.methods)if err != nil {fmt.Println("binary.Read failed:", err)}return m }func (c *proxyCoder) returnMethod() {buf := make([]byte, 2)buf[0] = 5buf[1] = 0c.conn.Write(buf)fmt.Println(buf) }func (c *proxyCoder) serve() {buf := make([]byte, 128)n, err := c.conn.Read(buf)if err != nil && err != io.EOF { panic(err) }fmt.Println(buf[:n])var s stringvar t stringvar i intif(buf[3] == 3){//domailfor i = 4; i < n-2; i++ {s += fmt.Sprintf("%c", buf[i])}} else {//ip4 or ip6s += fmt.Sprintf("%d", buf[4])for i = 5; i < n-2; i++ {s += fmt.Sprintf(".%d", buf[i])}}p := make([]byte, 2)var port uint16p[1] = buf[n-1]p[0] = buf[n-2]b := bytes.NewBuffer(p)err = binary.Read(b, binary.BigEndian, &port)if err != nil {fmt.Println("binary.Read failed:", err)}s += fmt.Sprintf(":%d", port)switch buf[1] {case 1://TCPt = "tcp"case 2://BINDcase 3://UDPt = "udp"}conn, err := net.Dial(t, s)if err != nil {fmt.Printf("%s connect error %s\n", t, s)buf[1] = 4c.conn.Write(buf[:n])c.conn.Close()return}buf[1] = 0c.conn.Write(buf[:n])fmt.Printf("%s connect success %s\n", t, s)go serv(conn, c.conn)go serv(c.conn, conn) }func serv(in net.Conn, out net.Conn){b := make([]byte, 10240)for ;;{n, err := in.Read(b)if( err != nil ){fmt.Printf("close\n")in.Close()out.Close()return}fmt.Printf("serv %d\n", n)out.Write(b[:n]);}}type Proxy struct { }func NewProxy() *Proxy {return &Proxy{} }var DefaultProxy = NewProxy()func (p *Proxy) ProxyConn(conn net.Conn ){c := &proxyCoder{conn}m := c.readMethods()fmt.Println(m)c.returnMethod()c.serve() }func handleConnection(conn net.Conn){buf := make([]byte, 1024)n, err := conn.Read(buf)if err != nil && err != io.EOF { panic(err) }fmt.Println(buf[:n])//answerbuf[0] = 5buf[1] = 0conn.Write(buf[:2])fmt.Println(buf[:2])//serven, err = conn.Read(buf)if err != nil && err != io.EOF { panic(err) }fmt.Println(buf[:n])conn.Close() }func main() {ln, err := net.Listen("tcp", ":1080")if err != nil {fmt.Printf("bind error\n")return}for {conn, err := ln.Accept()if err != nil {fmt.Printf("accept error\n")continue}go DefaultProxy.ProxyConn(conn)//go handleConnection(conn)} }
参考推荐:
Go语言下载、安装、配置、使用
Google的编程样式
Go http访问使用代理
转载于:https://my.oschina.net/sunboy2050/blog/1545028
Go语言的变量、函数、Socks5代理服务器相关推荐
- Go语言的变量、函数、Socks5代理服务器 1
Go语言中变量的声明和JavaScript很像,使用var关键字,变量的声明.定义有好几种形式 1. 变量和常量 // 声明并初始化一个变量 var m int = 10 // 声明初始化多个变量 v ...
- R语言使用aov函数进行单因素协方差分析(One-way ANCOVA)、单因素协方差分析(ANCOVA)扩展了单因素方差分析,包括一个或多个协变量(covariates)
R语言使用aov函数进行单因素协方差分析(One-way ANCOVA).单因素协方差分析(ANCOVA)扩展了单因素方差分析,包括一个或多个协变量(covariates) 目录
- R语言使用lm函数拟合多元线性回归模型、假定预测变量没有交互作用(Multiple linear regression)
R语言使用lm函数拟合多元线性回归模型.假定预测变量没有交互作用(Multiple linear regression) 目录
- R语言使用anova函数进行方差分析比较两个回归分析模型的差异、从而决定是否删除某些预测变量(Comparing nested models using the anova function)
R语言使用anova函数进行方差分析比较两个回归分析模型的差异.从而决定是否删除某些预测变量(Comparing nested models using the anova function) 目录
- R语言编写自定义函数、评估回归模型预测变量的相对重要性(Relative importance)、通过在所有可能的子模型中添加一个预测变量而获得的R方的平均增加、评估预测变量的重要度、并通过点图可视化
R语言编写自定义函数.评估回归模型预测变量的相对重要性(Relative importance).通过在所有可能的子模型中添加一个预测变量而获得的R方的平均增加.来评估预测变量的重要程度.并通过点图可 ...
- R语言使用table函数计算单分类变量的频率表(frequency table)、使用prop.table函数将table函数计算获得的频率表转化为比率表、返回单分类变量每一个类别的比率、或者百分比
R语言使用table函数计算单分类变量的频率表(frequency table).使用prop.table函数将table函数计算获得的频率表转化为比率表.返回单分类变量每一个类别的比率.或者百分比. ...
- R语言as.numeric函数将因子变量(factor)转化为数值变量(Numeric)
R语言as.numeric函数将因子变量(factor)转化为数值变量(Numeric) 目录 R语言as.numeric函数将因子变量(factor)转化为数值变量(Numeric) #基本语法
- C语言写一函数交换两变量的值
C语言写一函数交换两变量的值 #include <stdio.h> void swap(int *p1, int *p2); // 形参,只声明 int main(){int a=5, b ...
- 在c语言中函数的定义变量的值为,变量定义(C语言中变量的声明和定义)
变量定义(C语言中变量的声明和定义),哪吒游戏网给大家带来详细的变量定义(C语言中变量的声明和定义)介绍,大家可以阅读一下,希望这篇变量定义(C语言中变量的声明和定义)可以给你带来参考价值. 3.函数 ...
最新文章
- SQLServer镜像状态异常排查
- Java rp api_Java初级--常用的API
- nginx 日志获取不到远程访问ip问题解决
- Flink从入门到放弃之源码解析系列-第1章 Flink组件和逻辑计划
- mongdb学习笔记
- linux 查看cpu_作为高级Java,你应该了解的Linux知识
- Leaf服务器框架从入门到放弃(一)认识Leaf和安装Leaf环境
- ORACLE 10g EXPDP,IMPDP使用方法
- 最佳实践 | 腾讯HTAP数据库TBase助力某省核心IT架构升级
- 移动端判断触摸的方向
- 解决微信小程序使用switchTab跳转后页面不刷新的问题
- Windows自带工具提取颜色得到十六进制颜色码
- OPA(运放)与MOS管组成的恒流源电路
- 机器学习之CART树
- centos7磁盘清理方法
- 分别用抽象类和接口实现四个动物类(鱼类、鸟类、爬行类、昆虫类)的类别和天赋
- 中国教育“善意的谎言”与恶果
- 怎样在M1或Intel Mac上重置NVRAM
- win10的wsapp把电脑卡死
- 【记录读论文时遇到的一些算法1】——MCMC sampling Gibbs sampling
热门文章
- hive 修改分桶数 分桶表_疯狂Hive之DDL操作二(三)
- vb 访问远程计算机,vb 连接远程服务器
- java皮肤库的框架_VC 添加皮肤库
- amf组网_【5G核心网】5G核心网SA组网方案及4G/5G互操作探讨
- hc sr04流程图_HC-SR04超声模块示例代码/原理图/说明书等全套资料
- android 下一步,在Android上单击“软键盘下一步”时,移至另一个EditText
- 正在检测服务器信息吗,云服务器会检测内容吗
- mysql事务隔离级别与具体实例
- printf 重新实现put_Go 实现海量日志收集系统(四)
- android override作用,Android Studio中@override的含义