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")
    }

}


上一篇下一篇

猜你喜欢

热点阅读