Go语言的变量、函数、Socks5代理服务器示例详解
来源:脚本之家
时间:2022-12-26 20:27:44 440浏览 收藏
知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《Go语言的变量、函数、Socks5代理服务器示例详解》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!
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 main import "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 main import ( "net" "fmt" "io" "bytes" "encoding/binary" ) type Methods struct{ ver, nmethods uint8 methods uint8 } type sock5cmd struct{ ver, cmd, rsv, atyp uint8 dst [255]uint8 } type proxyCoder struct { conn net.Conn } func (c *proxyCoder) readMethods() Methods { var m Methods b := 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] = 5 buf[1] = 0 c.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 string var t string var i int if(buf[3] == 3){//domail for i = 4; i总结
以上所述是小编给大家介绍的Go语言的变量、函数、Socks5代理服务器,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对golang学习网网站的支持!
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。
-
366 收藏
-
272 收藏
-
312 收藏
-
297 收藏
-
451 收藏
-
165 收藏
-
473 收藏
-
377 收藏
-
384 收藏
-
246 收藏
-
110 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习