go语言学习笔记
1、如果声明了的变量,或则引入了进来的包是没用过的,那么编译失败,status return 2,但是如果是一个全局变量不用,是可以的。
2、已经赋值了的变量不能再次赋值,不能用 := 再次赋值。但是是可以用 = 继续赋值的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" ) func main() { var c int = 2; var d = 2; d = 3; // can not use := replace the d fmt.Println(c); fmt.Println(d); }
3、不存在的变量可以直接用,d := 3直接用。但是不能d = 3这样。这样会提示引用不存在的变量。 但是直接用的,也不能声明在全局变量。
4、for语句变化太多了,不能加括号,也只能用 i++
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" ) const ( a = iota; b = iota; //这个iota没什么用的。 c; d; ) func main() { for i := 0; i < 5; i++ { // 只能这样, i++。。而且不能有括号。 fmt.Println(i); } }
5、感觉go语言其实就是类型后置了,确实有很多简便的地方,但是我还是想为每一个变量都声明一个类型。这样好看点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "unsafe" ) const ( a = iota b = iota c d ) func getMax(a, b int) int { //确实可以这样使得a和b都是int,但是不习惯 if a > b { return a } else { return b } } func toShow(a int, b float32, c int) (int, float32, int) { // 函数定义了,不用 return a, b, c } func main() { var str string = "12454353242434" fmt.Println(unsafe.Sizeof(str)) var sz int = len(str) fmt.Println(sz) fmt.Println(getMax(1, 2)) fmt.Println(toShow(1, 2, 3)) }
6、返回函数的函数。new功能,而且可以使用同一个变量一直用。称为函数的闭包
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" ) func getSequence() func() int { // 返回类型是 func() int var i int = 0 return func() int { i++ return i } } //带参数的函数 func getAddSequence() func(x int, y int) (int, int, int) { // 函数都是匿名的 var number int = 0 return func(x int, y int) (int, int, int) { number++ return number, x, y } } func main() { var nextNumber func() int = getSequence() // type func() int fmt.Println(nextNumber()) var nextAddNumber func(int, int) (int, int, int) = getAddSequence() fmt.Println(nextAddNumber(1, 2)) // type func(int, int) (int, int, int) }
7、数组初始化,居然不能array[0] = array[1] = 1;
分开来就行,我怀念c++了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" ) func getSequence() func() int { // 返回类型是 func() int var i int = 0 return func() int { i++ return i } } //带参数的函数 func getAddSequence() func(x int, y int) (int, int, int) { // 函数都是匿名的 var number int = 0 return func(x int, y int) (int, int, int) { number++ return number, x, y } } func main() { var nextNumber func() int = getSequence() // type func() int fmt.Println(nextNumber()) var nextAddNumber func(int, int) (int, int, int) = getAddSequence() fmt.Println(nextAddNumber(1, 2)) // type func(int, int) (int, int, int) var arrayc [2]int arrayc[0] = arrayc[1] = 1; var array = [3]int{0, 1, 2} // 数组直接初始化,要这样,先等于 for i := 0; i < len(array); i++ { fmt.Println(i) } }
8、go语言中不用考虑变量的生存周期,系统会自动回收,或则自动保留。但是还是要注意效率问题。
这里显示结构体初始化方法(一直忘记T__T)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import "fmt" type speakable interface { speak() } type Person struct { a int b int } func (person *Person) speak() int { return person.a + person.b } func (person *Person) call() { fmt.Println("fff") } func main() { person := Person{a: 1, b: 2} // atttion fmt.Println(person.speak()) person.call() }
9、做了一个题目,学习了go'语言的输入是怎样的
http://codeforces.com/problemset/problem/914/A
package main
two methond for scan
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "bufio" "fmt" "math" "os" "strconv" ) func get(s *bufio.Scanner) int { succ := s.Scan() if !succ { for { } } res, _ := strconv.ParseInt(s.Text(), 10, 0) return int(res) } func main() { var n int // var a int s := bufio.NewScanner(os.Stdin) s.Split(bufio.ScanWords) n = get(s) ans := -19999999 for i := 0; i < n; i++ { var a int a = get(s) if a < 0 { if ans < a { ans = a } } else { t := int(math.Floor(math.Sqrt(float64(a)))) if t*t != a && ans < a { ans = a } } } fmt.Println(ans) }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import "fmt" import ( "bufio" "math" "os" ) func main() { var n int // var a int input := bufio.NewReader(os.Stdin) fmt.Fscan(input, &n) ans := -19999999 for i := 0; i < n; i++ { var a int fmt.Fscan(input, &a) if a < 0 { if ans < a { ans = a } } else { t := int(math.Floor(math.Sqrt(float64(a)))) if t*t != a && ans < a { ans = a } } } fmt.Println(ans) }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "bufio" "fmt" "os" "strconv" "time" ) func str2Time(str string) time.Time { loc, _ := time.LoadLocation("Local") the_time, _ := time.ParseInLocation("2006-01-02", str, loc) return the_time } func getInt(s *bufio.Scanner) int { succ := s.Scan() if !succ { for { } } res, _ := strconv.ParseInt(s.Text(), 10, 0) return int(res) } func getStr(s *bufio.Scanner) string { succ := s.Scan() if !succ { for { } } return s.Text() } var local int func ok(str1 string) int { str := str1[:4] str += str1[5:7] str += str1[8:10] be, en := 0, 7 for { if be >= en { return 1 } if str[be] != str[en] { return 0 } be++ en-- } return 0 } func main() { day, _ := time.ParseDuration("24h") var n int s := bufio.NewScanner(os.Stdin) s.Split(bufio.ScanWords) n = getInt(s) for i := 0; i < n; i++ { var be, en string be = getStr(s) en = getStr(s) beTime := str2Time(be) enTime := str2Time(en) enTime = enTime.Add(day) ans := 0 for ; beTime.Before(enTime); beTime = beTime.Add(day) { ans += ok(beTime.String()[:10]) } fmt.Println(ans) } }
10、关于指针变量方法的
常量方法,明显可以转换成一个指针方法
func (p struct) fun() {} 换转换成一个 func(p *struct) fun() { (*p).fun() } 这样转换,毫无损失
但是指针变量方法就不能转换成常量变量方法了,因为
fun (p *struct) fun() { 可能要改变*p的值 } 你变成了 fun(p struct) fun() { (&p).fun() },这里改变的会是形参p的值,和预期不同。
指针方法,编译器帮我们转换了,变成(&t).xxx
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" ) type face interface { value_show() point_show() } type Interger int func (a Interger) value_show() { fmt.Println(a) } func (a *Interger) point_show() { fmt.Println(*a) } func main() { var point *Interger = new(Interger) *point = 12 point.point_show() // correct point.value_show() // correct,这个因为编译器会帮value_show生成一个指针版本 var value Interger = 333 value.value_show() // correct value.point_show() // 这个非指针变量,为什么可以调用point_show方法??? //(&value).point_show() // 隐式转换成这个样子 //测试,开一个接口,证明非指针变量并没有完全实现接口要求的所有方法,所以不能赋值 var test_point face = point // ok it`s correct,编译没错误 fmt.Println(test_point) var test_value face = value //这里会报错的,没有实现point_show方法 fmt.Println(test_value) }
11、接口类型查询,要询问某个接口变量是否是xxx接口,只需要 _, ok := value.(xxx),如果是,则ok放回true,要注意那个xxx只能填入接口类型
12、查询是否某个数据类型:switch v := v1.(type) { case int: case string: }
这个骚东西,需要v1是接口类型才可以的,所以需要
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
func show(x interface{}) { switch x.(type) { case string: fmt.Println(1) case int: fmt.Println(2) case []string: fmt.Println(3) case map[string][]string: fmt.Println(4) } }
也可以使用放射机制:http://blog.sina.com.cn/s/blog_487109d101013g2p.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "encoding/json" "fmt" "reflect" ) type vimi struct { Mp map[string][]string `json : "haha"` // Ch chan int } func show(x interface{}) { switch x.(type) { case string: fmt.Println(1) case int: fmt.Println(2) case []string: fmt.Println(3) case map[string][]string: fmt.Println(4) } } func main() { var test vimi // test.Ch = make(chan int, 4) // test.Ch <- 1 test.Mp = make(map[string][]string) test.Mp["vimi"] = append(test.Mp["vimi"], "test_one") test.Mp["vimi"] = append(test.Mp["vimi"], "test_two") fmt.Printf("%+v\n", test) res, er := json.Marshal(test) fmt.Println(er) fmt.Println(string(res)) mp := make(map[string][]string) mp["vimi"] = append(mp["vimi"], "baby_one") mp["vimi"] = append(mp["vimi"], "baby_two") mp_json, _ := json.Marshal(mp) fmt.Println(string(mp_json)) ch := make(chan int, 4) ch <- 1 ch <- 2 ch <- 3 ch_json, err := json.Marshal(ch) fmt.Println(err) fmt.Println(string(ch_json)) fmt.Println("-----") fmt.Println(reflect.TypeOf(mp)) show(mp) }
13、go语言用json的时候,struct里面的字段开头字母都要大写啊啊啊啊啊,不然读入不成功日日日,也可能需要P109
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "encoding/json" "fmt" ) type test_json struct { Id string //这个一定要大写 Name string } const js = `{"name":"vimi", "id":"2015"} {"name":"stupidone", "id":"2014"}` var jjss = []byte(`[{"name": "vimi", "id": "2015"}, {"name": "stupidone", "id": "2014"}]`) var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) type Animal struct { Name string Order string } // const jsonStream = ` // {"Name": "Ed", "Text": "Knock knock."} // {"Name": "Sam", "Text": "Who's there?"} // {"Name": "Ed", "Text": "Go fmt."} // {"Name": "Sam", "Text": "Go fmt who?"} // {"Name": "Ed", "Text": "Go fmt yourself!"} // ` func main() { var a []test_json err := json.Unmarshal(jjss, &a) fmt.Println(err) fmt.Println(a) fmt.Printf("%+v", a) // var animals []Animal // err := json.Unmarshal(jsonBlob, &animals) // if err != nil { // fmt.Println("error:", err) // } // fmt.Printf("%+v", animals) }
14、一个[]byte的json字节数组,只能转化成一个struct
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "encoding/json" "fmt" // "io" // "strings" ) type test_json struct { Name string Id int } const js = `{"name":"vimi", "id":"2015"} {"name":"stupidone", "id":"2014"}` var jjss = []byte(`[{"name":"vimi", "id":2015}, {"name":"stupidone", "id":2014}]`) // const jsonStream = ` // {"Name": "Ed", "Text": "Knock knock."} // {"Name": "Sam", "Text": "Who's there?"} // {"Name": "Ed", "Text": "Go fmt."} // {"Name": "Sam", "Text": "Go fmt who?"} // {"Name": "Ed", "Text": "Go fmt yourself!"} // ` func main() { var a test_json a.Id = 2015 a.Name = "刘炜铭" var b []byte var err error b, err = json.Marshal(a) fmt.Println(b, err) var _a_ test_json liu := json.Unmarshal(b, &_a_) // 一个这样的[]byte类型,只能转成一个实例,所以这里_a_不是数组 fmt.Println(liu) fmt.Printf("%+v", _a_) // dec := json.NewDecoder(strings.NewReader(js)) // for { // var m test_json // err := dec.Decode(&m) // if err == io.EOF { // break // } else if err != nil { // // fmt.Println("ff") // } // fmt.Println(m.Name, m.Id) // } }
但是这的jjss也只是一个[]byte而已,编译额时候就叫我传数组了,检测到了吗
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "encoding/json" "fmt" // "io" // "strings" ) type test_json struct { Name string Id int } const js = `{"name":"vimi", "id":"2015"} {"name":"stupidone", "id":"2014"}` var jjss = []byte(`[{"name":"vimi", "id":2015}, {"name":"stupidone", "id":2014}]`) // const jsonStream = ` // {"Name": "Ed", "Text": "Knock knock."} // {"Name": "Sam", "Text": "Who's there?"} // {"Name": "Ed", "Text": "Go fmt."} // {"Name": "Sam", "Text": "Go fmt who?"} // {"Name": "Ed", "Text": "Go fmt yourself!"} // ` func main() { var a test_json a.Id = 2015 a.Name = "刘炜铭" var b []byte var err error b, err = json.Marshal(a) fmt.Println(b, err) var _a_ []test_json liu := json.Unmarshal(jjss, &_a_) // 一个这样的[]byte类型,只能转成一个实例,所以这里_a_不是数组 fmt.Println(liu) fmt.Printf("%+v", _a_) // dec := json.NewDecoder(strings.NewReader(js)) // for { // var m test_json // err := dec.Decode(&m) // if err == io.EOF { // break // } else if err != nil { // // fmt.Println("ff") // } // fmt.Println(m.Name, m.Id) // } }
即使jjss是一个struct的信息,也是传数组
15、不知道为什么同一个包中,不能问各自的变量,但是在不同的包中是可以的。只需要导入对应的包就行。但是在同一个包中是不可以导入包的因为这样会导致重复导入。没解决,但是只要你代码没写错在不同的包中是可以运行的。。
16、要使你的任何东西,在其他包中可见,就必须要大写字母开头。包括一个结构体的里面的字段名, OR 函数
--------------------------------------2018年01月29日16:42:24-------------------------------------------
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "log" "net/http" "strings" ) func sayHelloName(w http.ResponseWriter, r *http.Request) { fmt.Println("-------------------") r.ParseForm() fmt.Println("----", r) fmt.Println(r.Form) fmt.Println("path : ", r.URL.Path) fmt.Println("scheme : ", r.URL.Scheme) fmt.Println("r.Form : ", r.Form["url_log"]) for k, v := range r.Form { fmt.Println("key:", k) fmt.Println("value:", strings.Join(v, " ")) } fmt.Fprint(w, "Hello") } func main() { http.HandleFunc("/", sayHelloName) err := http.ListenAndServe(":9090", nil) if err != nil { log.Fatal("listen and serve: ", err) } }
.gtpl路径,代码上用的是相对路径,怎么知道呢,创建一个文件看看就知道了
go run创建的相对目录会在.exec目录下,但是自己go build的,运行后却不在对应目录下。(OS 9中),windows的正常
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "html/template" "log" "net/http" "strings" ) func sayHelloName(w http.ResponseWriter, r *http.Request) { fmt.Println("-------------------") fmt.Println("-------------------") r.ParseForm() fmt.Println(r.Method) //fmt.Println("----", r) fmt.Println(r.Form) fmt.Println("path : ", r.URL.Path) fmt.Println("scheme : ", r.URL.Scheme) fmt.Println("r.Form : ", r.Form["url_log"]) for k, v := range r.Form { fmt.Println("key:", k) fmt.Println("value:", strings.Join(v, " ")) } fmt.Fprint(w, "Hello") } func login(w http.ResponseWriter, r *http.Request) { fmt.Println("********************") r.ParseForm() fmt.Println("method : ", r.Method) if r.Method == "GET" { t, err := template.ParseFiles("login.gtpl") //这里是相对路径的 log.Println(t.Execute(w, nil)) } else { r.ParseForm() fmt.Println("username : ", r.Form["username"]) fmt.Println("password : ", r.Form["password"]) } } func main() { /*不知道相对路径的,可以用os.create来看看系统是在那里创建的*/ http.HandleFunc("/", sayHelloName) http.HandleFunc("/login", login) err := http.ListenAndServe(":9090", nil) if err != nil { log.Fatal("listen and serve: ", err) } }
初始化字段,和C++一样的Node{},这里用了 花括号{}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" ) type Node struct { mp map[string][]string ch chan int } func main() { var vimi Node = Node{make(map[string][]string), make(chan int, 4)} vimi.mp["vimi"] = []string{"test_one", "test_two"} }
json不能解析map吗? && json.MarshalIndent
不是的,是因为json不能解析chan,一切都是因为有了chan。还有要注意变量全部得大写,才可以json成功。还有可以把err输出出来看看的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "encoding/json" "fmt" ) type Node struct { Mp map[string][]string MMM map[string]int Ch chan int } type Test struct { Name string `json : "vimi"` } func main() { var vimi Node = Node{make(map[string][]string), make(map[string]int), make(chan int, 4)} vimi.Mp["vimi"] = []string{"test_one", "test_two"} vimi.MMM["vimi"] = 2 vimi.Ch <- 2 res_by, _ := json.MarshalIndent(vimi, "", "\t") fmt.Println(string(res_by)) var vimi_test Test = Test{"vimi"} res_test, _ := json.MarshalIndent(vimi_test, "", "\t") fmt.Println(string(res_test)) }
解析json中,json.Unmarshal(date, interface{})中,interface应该传怎样的参数
首先回顾一下,C语言的memset
http://www.cnblogs.com/liuweimingcprogram/p/4973254.html
而且,用reflect.TypeOf可以知道数据类型,用unsafe.Sizeof可以知道数据大小。那么够了
首先:传指针和传变量的一个大区别就是能否改变值。传变量一般都是值传递(引用类型除外)
那么,传指针是肯定的了。
然后:
&p : 地址 + sizeof = 8
&&p :地址 + sizeof = 8
明显,地址的地址,还是那个地址(数值上)
加上有sizeof固定死了。解引用的时候也会做到一个一个解引用。所以这两种方法都是可以的。
-----------------------------------------------------------------------------------------------------------------------------------------------
1、在某个时间点运行程序,可以用
timer1 := time.NewTimer(time.Second * 2) <-timer1.C fmt.Println("Timer 1 expired")
2、上面那个是,2秒后,放一个ch去timer.C,但是如果想一直运行的,可以用Ticker,每隔2秒放一次
不stop,就一直放
package main import ( "fmt" "time" ) func main() { t := time.NewTicker(time.Second) go func() { for r := range t.C { fmt.Println(r) } }() time.Sleep(time.Second * 5) t.Stop() fmt.Println("finish") }
3、go语言中, 那个os.Args[0]代表有多少个参数,空格分开的。传入的话,用
client.exe 127.0.0.1
那么os.Args[0] = 1
os.Args[1] = "127.0.0.1"
千万不要加--,被坑了
【这个是错误的】
----------------------------------------------------2018-05-23 15:34:33-------------------------------------------------------------------
1、go中flags的使用
go run main.go --word 23 -numb 2 --fork --svar f
wordPtr := flag.String("word", "foo", "a string") 放回一个string的指针,解析附带的参数中 --word后面的字段,如果为空,则是foo(默认字段)
var svar string
flag.StringVar(&svar, "svar", "bar", "a string var") 不想用指针也可以这样的
boolPtr := flag.Bool("fork", false, "a bool") 特别要注意的是bool变量,只要加上 --fork字段,就是true,不加就是false,不需要--fork true这样,会错误的
// Once all flags are declared, call `flag.Parse()`
// to execute the command-line parsing.
flag.Parse() 开始解析
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// [_Command-line flags_](http://en.wikipedia.org/wiki/Command-line_interface#Command-line_option) // are a common way to specify options for command-line // programs. For example, in `wc -l` the `-l` is a // command-line flag. package main // Go provides a `flag` package supporting basic // command-line flag parsing. We'll use this package to // implement our example command-line program. import ( "flag" "fmt" "os" ) func main() { // Basic flag declarations are available for string, // integer, and boolean options. Here we declare a // string flag `word` with a default value `"foo"` // and a short description. This `flag.String` function // returns a string pointer (not a string value); // we'll see how to use this pointer below. wordPtr := flag.String("word", "foo", "a string") // This declares `numb` and `fork` flags, using a // similar approach to the `word` flag. numbPtr := flag.Int("numb", 42, "an int") boolPtr := flag.Bool("fork", false, "a bool") // It's also possible to declare an option that uses an // existing var declared elsewhere in the program. // Note that we need to pass in a pointer to the flag // declaration function. var svar string flag.StringVar(&svar, "svar", "bar", "a string var") // Once all flags are declared, call `flag.Parse()` // to execute the command-line parsing. flag.Parse() // Here we'll just dump out the parsed options and // any trailing positional arguments. Note that we // need to dereference the pointers with e.g. `*wordPtr` // to get the actual option values. fmt.Println("word:", *wordPtr) fmt.Println("numb:", *numbPtr) fmt.Println("fork:", *boolPtr) fmt.Println("svar:", svar) fmt.Println("tail:", flag.Args()) fmt.Println(os.Args) }
如果需要使用os.Getenv("Telegram_Token")这样的话,需要在~/.zshrc文件中添加
export Telegram_Token=xxxxx
然后,select{}的话是一个死循环,直到有一个被触发了
golang静态编译,什么是静态编译?
https://tonybai.com/2017/06/27/an-intro-about-go-portability/
------------------------------- 2018年10月16日15:39:11 -------------------------------------
go语言的文件分成三种:
1、命令源码文件(有main函数的,然后goinstall的话会放去你的gobin目录下,go build的话生成在当前目录)
2、库源码文件 (就是没有main的,然后goinstall的话会放去pkg名录下以.a结尾,go build的话是没有用的,只会检查语法)
3、测试文件。
go get中:
-x : 也是显示
-u : 更新已经下载过的包
-fix : 转换编译版本到本地最新那个go-1.10
posted on 2018-01-23 16:02 stupid_one 阅读(604) 评论(0) 编辑 收藏 举报