Go一些简要知识
2018-06-12 本文已影响10人
小Q逛逛
Go简要知识
1.程序结构
package main
import(
"fmt"
)
func main(){
fmt.Println("Hello world!")
}
2.变量声明和赋值,三种格式
var msg string = "Hello world!"
var msg2 = "Hello world!"
msg := "Hello world!"
3.常量const
const(
prizeDay = "Wednesday"
prizeFund = 10000
)
func main(){
/*
常量不能第二次赋值,回报错
cannot assign to prizeDay
cannot assign to prizeFund
*/
prizeDay = "Wednesday"
prizeFund = 10000
}
4.数字类型
func main(){
int1 := 2
int2 := 3
fp1 := 22.0
fp2 := 4.5
fmt.Printf("%d + %d = %d\n", int1, int2, int1 + int2)
fmt.Printf("%f / %f = %f\n", fp1, fp2, fp1 / fp2)
fmt.Printf("type: %s\n",reflect.TypeOf(fp1)) //float64
}
5.Booleans:true,false
trueValue && trueValue //true
trueValue && falseValue //false
trueValue || falseValue //true
trueValue || trueValue //true
!trueValue //false
6.strings,默认""
str1 = "There is a tab between this\tand this"
str2 = "There is a tab between this\tand this"
//常用操作
//1.拼接 +
str1 + str2
//长度
len(str1)
//子串
str1[0:4]
str1[17:23]
str1[:10]
str1[22:]
str1 > str2
7.字符串转换
i,err := strconv.Atoi("33")
str := strconv.Itoa(33)
//
ParseBool,ParseFloat,ParseInt,ParseUint
FormatBool,FormatFloat,FormatInt,FormatUnit
8.if/else
if a == 1{
//to do
}else {
//to do
}
if a == 1{
//to do
}else if{
//to do
}else {
//to do
}
9.for
for init;condition;post{
//run commands until condition is true
}
for{
//the statement in this block execute forever
}
total := 1
for{
if total > 1000{
break
}
total += 1
}
for i := 1;i <= 5;i++{
fmt.Printf("num:%d \n",i)
}
total = 1
for total < 10000{
total += total
}
10.switch
var anum = 1
switch anum {
case 1:
fmt.Println("00000")
case 2:fmt.Println("11111")
default:
fmt.Println("default")
}
numDaysInMonth := 30
switch {
case numDaysInMonth >= 28 && numDaysInMonth <=29:
fmt.Println("February")
case numDaysInMonth == 30:
fmt.Println("April, June, September, November")
case numDaysInMonth == 31:
fmt.Println("January, March, May, July, August, October, December")
}
func letters(){
numAtoI, numJtoR, numStoZ, numSpaces, numOther := 0, 0, 0, 0, 0
sentence := os.Args[1]
for i := 1; i < len(sentence); i++ {
letter := string(sentence[i])
switch letter {
case "a","b","c","d","e","f","g","h","i":
numAtoI += 1
case "j","k","l","m","n","o","p","q","r":
numJtoR += 1
case "s","t", "u", "v", "w", "x", "y", "z":
numStoZ += 1
case " ":
numSpaces += 1
default:
numOther += 1
}
}
fmt.Printf("A to I: %d\n", numAtoI) fmt.Printf("J to R: %d\n", numJtoR) fmt.Printf("S to Z: %d\n", numStoZ) fmt.Printf("Spaces: %d\n", numSpaces) fmt.Printf("Other: %d\n", numOther)
}
11.Arrays,作为函数参数,传地址
var nums [6]int
var strings [3]string
totals := [5]int{1,2,3,4,5}
totals2 := [...]int{1,2,3,4,5}
for _,value := range totals {
fmt.Println(value)
}
12.slice,切片
fruits := []string{"Apples","Oranges","Bananas","Kiwis"}
fmt.Printf("%v\n", fruits[1:3])
fmt.Printf("%v\n", fruits[0:2])
fmt.Printf("%v\n", fruits[:3])
fmt.Printf("%v\n", fruits[2:])
/*
[oranges bananas]
[apples oranges]
[apples oranges bananas]
[bananas kiwis]
*/
//创建slice
mySlice := make([]int,[len])
mySlice := make([]int, 4, 8)
fmt.Printf("Initial Length: %d\n", len(mySlice)) fmt.Printf("Capacity: %d\n", cap(mySlice)) fmt.Printf("Contents: %v\n", mySlice)
//append,如果capacity不足,会加大目前的一倍
mySlice = append(mySlice, 1, 3, 5, 7)
mySlice[cap+1] = 88//这样的方式会越界报错,只能使用append增加元素
//copy
mySlice := make([]int, 0, 8)
mySlice = append(mySlice, 1, 3, 5, 7, 9, 11, 13, 17)
mySliceCopy := make([]int, 8)
copy(mySliceCopy, mySlice)
12.maps,字典
actor := make(map[string]int)//key:string value:int
actor["Paltrow"] = 43
actor["Cruise"] = 53
actor["Redford"] = 79
actor["Diaz"] = 43
actor["Kilmer"] = 56
actor["Pacino"] = 75
actor["Ryder"] = 44
fmt.Printf("Robert Redford is %d years old\n", actor["Redford"])
fmt.Printf("Cameron Diaz is %d years old\n", actor["Diaz"])
fmt.Printf("Val Kilmer is %d years old\n", actor["Kilmer"])
//读取值
if age, ok := actor["Hopkins"]; ok {
fmt.Printf("Anthony Hopkins is %d years old\n", age)
} else {
fmt.Println("Actor not recognized.")
}
//map是无序的
for i := 1; i < 4; i++ {
fmt.Printf("\nRUN NUMBER %d\n", i)
for key, value := range actor {
fmt.Printf("%s : %d years old\n", key, value)
}
}
//排序key打印map
// Store the keys in a slice
var sortedActor []string
for key := range actor {
sortedActor = append(sortedActor, key) }
// Sort the slice alphabetically
sort.Strings(sortedActor)
/* Retrieve the keys from the slice and use them to look up the map values */
for _, name := range sortedActor {
fmt.Printf("%s : %d years old\n", name, actor[name])
}
13.structs
type rect struct {
height int
width int
}
r := rect{height:12,width:20}
fmt.Printf("Height: %d\nWidth: %d\n", r.height, r.width)
//获取struct指针
var myRectangle *rect
//或者 myRectangle := new(rect),简写
myRectangle := &rect{
height:12,
width:20,
}
//方法
func (r rect)area()int{
return r.height * h.width
}
//修改值的时候传指针
func (r *rect)double(){
r.height *= 2
r.width *= 2
}
14.匿名内部的类
type Discount struct{
percent float32
promotionId string
}
type ManagersSpecial struct{
Discount //The embedded type
extraoff float32
}
januarySale := Discount{15.00, "January"} managerSpecial := ManagersSpecial{januarySale, 10.00}
managerSpecial.Discount.percent // "15.00 managerSpecial.Discount.promotionId // "January"
//访问匿名内部类的方法
managerSpecial.Discount.someMethod(someParameter)
15.interface,接口
type Greeter interface{
SayHi() string
}
type Person struct{
Name string
}
type Animal struct{
Sound string
}
func (p Person)SayHi()string{
return "Hello! My name is " + p.name
}
func (a Animal)SayHi()string{
return a.Sound
}
func greet(i Greeter){
fmt.Println(i.SayHi())
}
func main() {
man := Person{Name: "Bob Smith"}
dog := Animal{Sound: "Woof! Woof!"}
fmt.Println("\nPerson : ")
greet(man)
fmt.Println("\nAnimal : ")
greet(dog)
}
16.empty interface:类似object
func main(){
displayType(42)
displayType(3.14)
displayType("ここでは文字列です")
}
func displayType(i interface{}) {
switch theType := i.(type) {
case int:
fmt.Printf("%d is an integer\n", theType)
case float64:
fmt.Printf("%f is a 64-bit float\n", theType)
case string:
fmt.Printf("%s is a string\n", theType) default:
fmt.Printf("I don't know what %v is\n", theType) }
}
17.类型判断
func main(){
var anything interface{} = "something"
aString := anything.(string)
fmt.Println(aString) //something
}
如果类型不能转,会报错
aInt := anything.(int)//panic
//修改为
aInt,ok := anything.(int)
if !ok{
fmt.Println("Cannot turn input into an integer")
}else {
fmt.Println(aInt)
}
18.Goroutines: go func()
func main(){
go message("goroutine")
message("normal")
fmt.Println("Hello world!")
}
func message(s string){
for i := 0;i<5;i++{
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
//gochannels
19.gochannel
myChannel := make(chan type)
func broadcast(c chan int){
for{
c <- rand.Intn(999)
}
}
func main(){
numberStation := make(chan int)
go broadcast(numberStation)
for num:= range numberStation{
time.Sleep(1000*time.Millisecond)
fmt.Printf("%d",num)
}
}
func generateAccount(accountNumberChannel chan int){
var accountNumber int
accountNumber = 30000001
for{
accountNumberChannel <- accountNumber
accountNumber += 1
}
}
func main(){
accountNumberChannel := make(chan int)
// start the goroutine that generates account numbers
go generateAccountNumber(accountNumberChannel)
fmt.Printf("SMITH: %d\n", <-accountNumberChannel)
fmt.Printf("SINGH: %d\n", <-accountNumberChannel)
fmt.Printf("JONES: %d\n", <-accountNumberChannel)
fmt.Printf("LOPEZ: %d\n", <-accountNumberChannel)
fmt.Printf("CLARK: %d\n", <-accountNumberChannel)
}
结果:
SMITH: 30000001
SINGH: 30000002
JONES: 30000003
LOPEZ: 30000004
CLARK: 30000005
code list2:close channel
func generateAccount(accountNumberChannel chan int){
var accountNumber int
accountNumber = 30000001
for{
if accountNumber > 30000005{
close(accountNumberChannel)
return
}
accountNumberChannel <- accountNumber
accountNumber += 1
}
}
func main(){
accountNumberChannel := make(chan int)
// start the goroutine that generates account numbers
go generateAccountNumber(accountNumberChannel)
// slice containing new customer names
newCustomers := []string{"SMITH", "SINGH", "JONES", "LOPEZ", "CLARK", "ALLEN"}
// get a new account number for each customer
for _, newCustomer := range newCustomers {
// is there anything to retrieve from the channel? accnum, ok := <-accountNumberChannel
if !ok {
fmt.Printf("%s: No number available\n",newCustomer)
} else {
fmt.Printf("%s: %d\n", newCustomer, accnum)
}
}
}
结果:
SMITH: 30000001
SINGH: 30000002
JONES: 30000003
LOPEZ: 30000004
CLARK: 30000005
20.Buffered channels
func main(){
c := make(chan int)
c <- 3
fmt.Println("ok")
}
/*
上面的代码运行会报错fatal error: all goroutines are asleep - deadlock!,原因在于把一个值放进没有缓冲的channnel,但没有读取出来,所以当我们使用了缓冲的channel时,不读取也不会报错
*/
func main(){
c := make(chan int,1)
c <- 3
fmt.Println("OK.")//ok.
}
//值得注意的是,如果赋值超过channel的容量,也会像上面那样报错fatal error: all goroutines are asleep - deadlock!
func main(){
c := make(chan int,1)
c <- 3
c <- 4
c <- 5
c <- 6
fmt.Println("OK.")//ok.
}
21.channel之间通信
func broadcast(nsChannel chan int, cChannel chan bool) {
numbers := []int{
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
}
i := 0
for {
select{
case nsChannel <- numbers[i]:
i += 1
if(i == len(numbers)){
i = 0
}
case <- cChannel:
cChannel <- true
return
}
}
func main(){
numbersStation := make(chan int)
completeChannel := make(chan bool)
go broadcast(numbersStation, completeChannel)
for i := 0; i < 100; i++ {
time.Millisecond) fmt.Printf("%d ", <-numbersStation)
}
<-completeChannel
fmt.Println("Transmission Complete.")
}
22.完整的小例子:获取网页的大小
package main
import (
"net/http"
"log"
"io/ioutil"
"sort"
"fmt"
)
type WebPage struct {
URL string
Size int
}
type WebPages []WebPage
//WebPages实现sort接口
func (slice WebPages)Len()int{
return len(slice)
}
func (slice WebPages)Less(i,j int)bool{
return slice[i].Size > slice[j].Size
}
func (slice WebPages)Swap(i,j int){
slice[i],slice[j] = slice[j],slice[i]
}
func (wp *WebPages)addElement(page WebPage){
*wp = append(*wp,page)
}
func getWebPageLength(url string,resultChannel chan WebPage){
res,err := http.Get(url)
if err != nil{
log.Fatal(err)
}
defer res.Body.Close()
size,err := ioutil.ReadAll(res.Body)
if err != nil{
log.Fatal(err)
}
var page WebPage
page.URL = url
page.Size = len(size)
resultChannel <- page
}
func main(){
urls := []string{
"http://www.syncfusion.com",
"http://www.baidu.com",
"http://www.microsoft.com",
"http://www.apple.com",
"https://www.jianshu.com/",
}
resultChannel := make(chan WebPage)
for _,url := range urls{
go getWebPageLength(url,resultChannel)
}
results := new(WebPages)
for range urls{
result := <-resultChannel
results.addElement(result)
}
sort.Sort(results)
for i,page := range *results{
fmt.Printf("%d. %s: %d bytes.\n", i+1, page.URL,
page.Size)
}
}
运行结果:
1. http://www.microsoft.com: 148284 bytes.
2. http://www.baidu.com: 116927 bytes.
3. http://www.syncfusion.com: 75030 bytes.
4. http://www.apple.com: 50073 bytes.
5. https://www.jianshu.com/: 43168 bytes.
22.net/http
package main
import (
"net/http"
"fmt"
)
func handler(w http.ResponseWriter,r *http.Request){
fmt.Fprintf(w,"Hello,%s!",r.URL.Path[1])
}
func main(){
http.HandleFunc("/",handler)
http.ListenAndServe(":9090",nil)
}
23.input,output
package main
import (
"io/ioutil"
"os"
)
func main(){
name := "test.txt"
txt := []byte("Not much in this file.")
if err := ioutil.WriteFile(name,txt,0755);err !=nil{
panic(err)
}
results,err := ioutil.ReadFile(name)
if err != nil{
panic(err)
}
println(string(results))
reader,err := os.Open(name)
if err != nil{
panic(err)
}
results,err = ioutil.ReadAll(reader)
if err != nil{
panic(err)
}
reader.Close()
println(string(results))
}
23.strings
package main
import (
"fmt"
"strings"
)
func main(){
fmt.Println(
// does "test" contain "es"?
strings.Contains("test", "es"),
// does "test" begin with "te"?
strings.HasPrefix("test", "te"),
// does "test" end in "st"?
strings.HasSuffix("test", "st"),
// how many times is "t" in test?
strings.Count("test", "t"),
// at what position is "e" in "test"?
strings.Index("test", "e"),
// join "input" and "output" with "/"
strings.Join([]string{"input", "output"}, "/"), // repeat "Golly" 6 times
strings.Repeat("Golly", 6),
/* replace "xxxx" with the first two
non-overlapping instances of "a" replaced by "b" */
strings.Replace("xxxx", "a", "b", 2),
/* put "a-b-c-d-e" into a slice using
"-" as a delimiter */
strings.Split("a-b-c-d-e", "-"),
// put "TEST" in lower case
strings.ToLower("TEST"),
// put "TEST" in upper case
strings.ToUpper("test"),
)
}
24.Errors
package main
import (
"errors"
"fmt"
)
func main(){
err := errors.New("error message")
fmt.Println(err)
}
25.containers
package main
import (
"container/list"
"fmt"
"container/ring"
"container/heap"
)
type OrderedNums []int
func (h OrderedNums)Len()int{
return len(h)
}
func (h OrderedNums)Less(i,j int)bool{
return h[i] < h[j]
}
func (h OrderedNums)Swap(i,j int){
h[i],h[j] = h[j],h[i]
}
func (h *OrderedNums)Push(x interface{}){
*h = append(*h,x.(int))
}
func (h *OrderedNums)Pop() interface{}{
old := *h
n := len(old)-1
x := old[n]
*h = old[:n]
return x
}
func main(){
l := list.New()
e0 := l.PushBack(42)
e1 := l.PushBack(11)
e2 := l.PushBack(19)
l.InsertBefore(7,e0)
l.InsertAfter(254,e1)
l.InsertAfter(4987,e2)
fmt.Println("*** LIST ***")
fmt.Println("-- Step 1:")
for e := l.Front();e != nil;e = e.Next(){
fmt.Printf("%d ",e.Value.(int))
}
fmt.Printf("\n")
l.MoveToFront(e2)
l.MoveToBack(e1)
l.Remove(e0)
fmt.Println("-- Step 2:")
for e := l.Front(); e != nil;e = e.Next(){
fmt.Printf("%d ",e.Value.(int))
}
fmt.Println()
//container/ring
blake := []string{"the", "invisible", "worm"}
r := ring.New(len(blake))
for i := 0; i < r.Len(); i++ {
r.Value = blake[i]
r = r.Next()
}
// move (2 % r.Len())=1 elements forward in the ring
r.Move(2)
fmt.Printf("\n *** RING ***")
r.Do(func(i interface{}) {
fmt.Printf("%s\n",i.(string))
})
//container/heap
h := &OrderedNums{34, 24, 65, 77, 88, 23, 46, 93}
heap.Init(h)
fmt.Printf("\n*** HEAP ***\n")
fmt.Printf("min: %d\n", (*h)[0])
fmt.Printf("heap:\n")
for h.Len() > 0 {
fmt.Printf("%d ", heap.Pop(h))
}
fmt.Printf("\n")
}
26.hash 和 cryptography
package main
import (
"os"
"hash/crc32"
"io"
"fmt"
)
func hash(filename string)(uint32,error){
f,err := os.Open(filename)
if err != nil{
return 0,err
}
defer f.Close()
h := crc32.NewIEEE()
_,err = io.Copy(h,f)
if err != nil{
return 0,err
}
return h.Sum32(),nil
}
func main(){
// contents of file1.txt: "Have I been tampered with?"
h1, err := hash("file1.txt")
if err != nil {
return
}
// contents of file2.txt: "I have been tampered with!"
h2, err := hash("file2.txt")
if err != nil {
return
}
if h1 == h2 {
fmt.Println(h1, h2, "Checksums match - files are identical")
} else {
fmt.Println(h1, h2, "Checksums don't match - files are different")
}
}