内容简介:&符号的意思是对变量取地址,如:变量a的地址是&a
判断和流程控制
https://www.jianshu.com/p/77be2afa225d
- if的使用,布尔判断条件不加括号;而且初始化的时候可以添加一个申明的初始值
if num == 3 { fmt.Println("index 3 :", i) }else{ fmt.Println(num) }
- switch 的使用:默认每个case自带break,如果想继续判断需要手动添加 fallthrough;有2种写法(直接switch 或者 switch i),适用不同的业务场景;case的值可以是整数,字符串等类型
//这种场景适用 条件值是固定的业务场景 i := 5 switch i{ case 1: fmt.Println("i is equal to 1") case 2: fmt.Println("i is equal to 2") case 3,4,5,6: fmt.Println("i is equal to 3,4,5 or 6") fallthrough default: fmt.Println("others") } //这种场景适用 条件值不固定,为某一区间的业务场景 switch { case i < 0: fmt.Println("小于零") case i > 0: fmt.Println("大于零") default: fmt.Println("等于零") }
- for循环:go的for循环有如下三种形式。条件不需要括号。for循环 数组和map的时候可以结合range一起用
for init; condition; post{} //和C的for一样 for condition{} //和while一样 for{} //结合break,continue nums := []int{2, 3, 4} for i, num := range nums { if num == 3 { fmt.Println("index 3 :", i) }else{ fmt.Println(num) } }
Golang的函数特征
- Go的函数支持多返回值,这方便编程,java实现多返回值只能封装在实体对象或者Hashmap中,典型的使用场景就是分页查询,既需要知道count,也需要当页的数据
func main(){ result1,result2 := swap("hello", "kitty") } func swap(x, y string) (string, string) { return y, x }
-
Go的函数写法和其它语言不一样,先申明变量的名字,再申明变量的类型。设计者觉得这样才符合正常人类的思维方式
-
Go函数和通过方法名的大小写来实现对外权限的控制
-
Go函数不支持重载
-
Go语言的函数的参数支持不指定数量和类型
func main(){ result := sum(3,5,7,9) fmt.Println("结果为:", result) } func sum(aregs ...int) int { s := 0 for _, number := range aregs{ s += number } return s }
Go对象的申明
- 申明一个对象,不需要再写冗余的get、set方法、机械式的构造函数、toString方法了,自带灵活的构造函数
- 支持三种类型的构造函数
- 另外通过(r *rect)来添加类的方法
type Books struct { title string author string subject string book_id int } func main() { var Book1 Books Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 fmt.Printf( "Book title : %s\n", book1.title); var Book2 Books=Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407} fmt.Println(Book2) fmt.Println(Book2.title) Book4 :=Books{ title:"testJson", subject:"testSubject", } } type rect struct { width int height int } func (r *rect) area() int { return r.width * r.height } func main() { r := rect{width: 10, height: 5} fmt.Println("area: ", r.area()) }
Go对象的继承和多态
- Go语言通过把目标对象当作自身成员变量的方式,间接的实现继承
func main(){ stu := Student{"chain"} fmt.Println(stu) aStu := AStudent{Student{"chain"}, 23} fmt.Println(aStu) } type Student struct{ name string } type AStudent struct{ Student Age int }
-
Go语言通过实现接口的方式,来实现多态,需要用到指针 &,不能指定为非 Phone接口的实现类,否则会报错
Go语言简洁归简洁,有时候过于简洁并不方便,比如不能知道这个类的接口是哪个接口
定义一个Phone的接口,它的实现类必须实现call()方法 type Phone interface { call() } 定义一个普通类NokiaPhone type NokiaPhone struct { } 实现call()的方法 func (nokiaPhone NokiaPhone) call() { fmt.Println("I am Nokia, I can call you!") } type IPhone struct { } func (iPhone IPhone) call() { fmt.Println("I am IPhone, I can call you!") } func main() { var phone Phone phone = &NokiaPhone{} phone.call() phone= &IPhone{} phone.call() }
Go中指针的使用 & 、 *
https://www.cnblogs.com/grimm/p/5623860.html
&符号的意思是对变量取地址,如:变量a的地址是&a
符号的意思是对指针取值,如: &a,就是a变量所在地址的值,当然也就是a的值了
是不可以抵消的
a和
&a是一样的,都是a的值,值为1 (因为*&互相抵消掉了)var a int = 1 var b *int = &a fmt.Println("a = ",a) //1 fmt.Println("&a = ",&a)//0xc00000a098 a的内存地址 fmt.Println("*&a = ",*&a)//1 *和&抵消掉了,还是1 fmt.Println("b = ",b) //0xc00000a098 b是a的指针,和 &a的值一样 fmt.Println("&b = ",&b) //0xc000006028 指针的指针 fmt.Println("*b = ",*b) //1 b指针指向的值
defer的用法
http://developer.51cto.com/art/201306/400489.htm
defer语句延迟执行一个函数,该函数被推迟到当包含它的程序返回时(包含它的函数 执行了return语句/运行到函数结尾自动返回/对应的goroutine panic/当前线程 runtime.Goexit())执行。
按照栈的形式后进先出的原则依次执行每个defer注册的函数。通常用来进行资源释放,错误的处理,清理数据等。
- defer是后进先出
//打印的顺序 main method 、method2、 method1,因为类似于栈模型,后进先出 func main() { defer doSomething("method 1") defer doSomething("method 2") fmt.Println("i am main method") } func doSomething(things string){ fmt.Println(" ia am doing somthing",things) }
- defer虽然是在当前方法执行后执行,但是defer的参数就会被实时解析。下面打印 1 0
func main() { i := 0 defer fmt.Println(i) //此时是0 i++ defer fmt.Println(i) //此时是1 }
- 经典的使用场景:简化资源的释放,用起来有类似finally的效果,特别适合多分支返回语句的情况,可以明显简化代码
func main() { fmt.Println(judgeNumber(-1)) fmt.Println(judgeNumber(0)) fmt.Println(judgeNumber(1)) } func judgeNumber(num int) string{ var lockName ="numlock" getLock(lockName) defer unlock(lockName) switch { case num<0 : return "nagetive" case num==0 : return "Zero" default: return "good number" } } func getLock(lockname string){ fmt.Println("i got the lock of ",lockname) } func unlock(lockname string){ fmt.Println("i release the lock of ",lockname) }
- defer是 Go 语言中 异常处理的一部分,和panic()、recover()一起使用
错误和异常处理机制
https://www.jianshu.com/p/f30da01eea97
- Golang中引入error接口类型作为错误处理的标准模式,如果函数要返回错误,则返回值类型列表中肯定包含error,可逐层返回,直到被处理。
- Golang中引入两个内置函数panic和recover来触发和终止异常处理流程,同时引入关键字defer来延迟执行defer后面的函数。
异常和错误的正确使用方式:
- 当错误的类型只有1种的时候,直接用bool,而不是用error的实现类,因为bool更简洁
//当hostType为 virtual_machine 或者bare_metal时校验通过,否则校验失败 func (self *AgentContext) IsValidHostType(hostType string) bool { return hostType == "virtual_machine" || hostType == "bare_metal" }
-
一般error的返回值放在返回值的最后一个
-
规范使用errors.New的使用,放在常量文件里面,标准化输出,而不是每次用的时候,自己定义输出内容
util.go 里面定义这样的常量 var ERR_NOT_EXIST = errors.New("file is not exist") 其它地方直接使用 err := createResource1() if err != nil { return ERR_CREATE_RESOURCE1_FAILED }
经典的异常和错误的使用方式
- 手动抛出异常:
if f < 0 { return 0, errors.New("math: square root of negative number") }
- 手动实现一个特定类型的异常类(类似于 java 的自定义Exception),需要实现Error接口的Error()方法
// 定义一个 DivideZeroError 结构,分母为0的专门的异常处理类 type DivideError struct { dividee int divider int } // 实现 `error` 接口 func (de *DivideError) Error() string { strFormat := ` Cannot proceed, the divider is zero. dividee: %d divider: 0 ` return fmt.Sprintf(strFormat, de.dividee) } // 定义 `int` 类型除法运算的函数 func Divide(varDividee int, varDivider int) (result int, errorMsg string) { if varDivider == 0 { dData := DivideError{ dividee: varDividee, divider: varDivider, } errorMsg = dData.Error() return } else { return varDividee / varDivider, "" } } func main() { // 正常情况 if result, errorMsg := Divide(100, 10); errorMsg == "" { fmt.Println("100/10 = ", result) } // 当被除数为零的时候会返回错误信息 if _, errorMsg := Divide(100, 0); errorMsg != "" { fmt.Println("errorMsg is: ", errorMsg) } }
- 通过defer实现一个未知可能类型的异常,类似于java的 try catch finally的用法,联合 panic() recover()一起使用
func main(){ defer func(){ if err := recover(); err != nil{ //捕捉异常并处理 fmt.Println("err: ", err) }}() if num, err := delive(20, -5); err == nil{ fmt.Printf("%f / %f = %f\n", 20.0, -5.0, num) }else{ fmt.Println(err) } if num, err := delive(20, 0); err == nil{ fmt.Printf("%f / %f = %f\n", 20.0, 0.0, num) }else{ fmt.Println(err) } fmt.Println("Test") } func delive(numA, numB float32) (float32, error){ if numB < 0{ return 0, errors.New("被除数不能为负数") }else if numB == 0{ panic("被除数不能为0") //抛出异常 }else{ return numA/numB, nil } }
Go的数据类型和转换
-
int 默认是和CPU的位数一样的,在64位的操作系统上,默认int就是64位,相当于java的long型数据
当然 int支持: int8 、int16、 int32、int64 - uint:无符号位的整形,就是没有符号位了,比如 int8 的范围是-127 到128,但是 uint8的范围是 0- 255
- 类型转换
var test string="120" //把test字符串转换为10进制的32位结果的数字 result,err:=strconv.ParseInt(test,10,32) if err!=nil{ fmt.Println(result) } count :=2000 resultResult:= strconv.Itoa(count)
import原理
https://blog.csdn.net/zhangzhebjut/article/details/25564457
- 按照import的先后顺序挨个引入依赖类,并且先执行依赖类的init方法,再执行自己的init方法,最后执行main方法
- 现在的1.11的版本,import还是加 相对路径吧;或者把工程路径放在 GOPATH/src下面。
- 路径前面加 . 的话,则可用直接引用,省略引用包名前缀
- import的话,还支持别名操作,和 _ 初始化假引用
- package下小写开头的方法对外不可见,类似于java中的private
import ( . "fmt" "./learn1" ) import( f “fmt” )
Server版helloWord
设置访问端口为 8888
- 设置不接受参数的网络请求
func main() { http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { fmt.Fprintln(writer,"<h1>hello kitty </h1>") }) http.ListenAndServe(":8888",nil) }
- 接收URL参数, 利用Fprintf使用格式化输出, %s为占位符,取的是 request中 参数name的值
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { fmt.Fprintf(writer,"<h1>hello kitty %s</h1>",request.FormValue("name")) })
- 并发型输出HelloWorld,1秒内开5000个微线程输出
func main() { for i :=0;i<5000;i++{ go printHelloWorld(i) } time.Sleep(time.Second) } func printHelloWorld(i int){ fmt.Printf("hello kitty ,%d \n",i) }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法导论(原书第2版)
[美] Thomas H.Cormen、Charles E.Leiserson、Ronald L.Rivest、Clifford Stein / 潘金贵 等 / 机械工业出版社 / 2006-9 / 85.00元
这本书深入浅出,全面地介绍了计算机算法。对每一个算法的分析既易于理解又十分有趣,并保持了数学严谨性。本书的设计目标全面,适用于多种用途。涵盖的内容有:算法在计算中的作用,概率分析和随机算法的介绍。书中专门讨论了线性规划,介绍了动态规划的两个应用,随机化和线性规划技术的近似算法等,还有有关递归求解、快速排序中用到的划分方法与期望线性时间顺序统计算法,以及对贪心算法元素的讨论。此书还介绍了对强连通子图......一起来看看 《算法导论(原书第2版)》 这本书的介绍吧!
HTML 编码/解码
HTML 编码/解码
html转js在线工具
html转js在线工具