1.3 Go学习之排序&异常处理&集合函数&字符串处理

排序

自然排序

  • 改变了source数据
package main

import (
    "fmt"
    "sort"
)

func main() {

    strs := []string{"c", "a", "b"}
    sort.Strings(strs)
    fmt.Println("Strings:", strs)

    ints := []int{7, 2, 4}
    sort.Ints(ints)
    fmt.Println("Ints:   ", ints)
//判断是否排序好
    s := sort.IntsAreSorted(ints)
    fmt.Println("Sorted: ", s)
}

定制排序

  • 需要实现sort接口的三个方法:Len,Less和Swap
package main

import (
    "fmt"
    "sort"
)

type byLength []string  //别名

func (s byLength) Len() int {
    return len(s)
}
func (s byLength) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}
//该方法实现是排序逻辑的关键
func (s byLength) Less(i, j int) bool {
    return len(s[i]) < len(s[j])
}

func main() {
    fruits := []string{"peach", "banana", "kiwi"}
    /implement our custom sort by converting the original fruits slice to byLength
    //and then use sort.Sort on that typed slice
    sort.Sort(byLength(fruits))
    fmt.Println(fruits)
}

//[kiwi peach banana]

panic

  • Go基于返回值方式来处理错误和异常
  • 基于fail fast策略来处理错误,或者先粗略地处理下错误

Mostly we use it to fail fast on errors that shouldn’t occur during normal operation, or that we aren’t prepared to handle gracefully.

package main

import "os"

func main() {

    panic("a problem")

    _, err := os.Create("/tmp/file")
    if err != nil {
        panic(err)
    }
}

panic: a problem
goroutine 1 [running]:
main.main()
    /.../panic.go:12 +0x47
...
exit status 2
非0状态结束运行

print an error message and goroutine traces, and exit with a non-zero status

Defer

  • 确保某函数能被执行,通常用于cleanup
  • 执行时机为函数scope的最后
package main

import (
    "fmt"
    "os"
)

func main() {
//This will be executed at the end of the enclosing function (main) 
//after writeFile has finished
    f := createFile("/tmp/defer.txt")
    defer closeFile(f)
    writeFile(f)
}

func createFile(p string) *os.File {
    fmt.Println("creating")
    f, err := os.Create(p)
    if err != nil {
        panic(err)
    }
    return f
}

func writeFile(f *os.File) {
    fmt.Println("writing")
    fmt.Fprintln(f, "data")

}

func closeFile(f *os.File) {
    fmt.Println("closing")
    err := f.Close()
//It’s important to check for errors when closing a file, even in a deferred function
    if err != nil {
        fmt.Fprintf(os.Stderr, "error: %v\n", err)
        os.Exit(1)
    }
}

Collection Functions

  • 类比Java的stream类
  • Go不支持泛型,取而代之的方式是collection functions
package main

import (
    "fmt"
    "strings"
)

func Index(vs []string, t string) int {
    for i, v := range vs {
        if v == t {
            return i
        }
    }
    return -1
}

func Include(vs []string, t string) bool {
    return Index(vs, t) >= 0
}

func Any(vs []string, f func(string) bool) bool {
    for _, v := range vs {
        if f(v) {
            return true
        }
    }
    return false
}

func All(vs []string, f func(string) bool) bool {
    for _, v := range vs {
        if !f(v) {
            return false
        }
    }
    return true
}

func Filter(vs []string, f func(string) bool) []string {
    vsf := make([]string, 0)
    for _, v := range vs {
        if f(v) {
            vsf = append(vsf, v)
        }
    }
    return vsf
}

func Map(vs []string, f func(string) string) []string {
    vsm := make([]string, len(vs))
    for i, v := range vs {
        vsm[i] = f(v)
    }
    return vsm
}

func main() {

    var strs = []string{"peach", "apple", "pear", "plum"}

    fmt.Println(Index(strs, "pear"))

    fmt.Println(Include(strs, "grape"))
//匿名函数
    fmt.Println(Any(strs, func(v string) bool {
        return strings.HasPrefix(v, "p")
    }))

    fmt.Println(All(strs, func(v string) bool {
        return strings.HasPrefix(v, "p")
    }))
//just inline the collection-manipulating code directly
//类比箭头函数
    fmt.Println(Filter(strs, func(v string) bool {
        return strings.Contains(v, "e")
    }))
//The above examples all used anonymous functions 
//but you can also use named functions of the correct type
    fmt.Println(Map(strs, strings.ToUpper))

}

2
false
true
false
[peach apple pear]
[PEACH APPLE PEAR PLUM]

String Functions

  • Go uses UTF-8 encoded strings
package main

import (
    "fmt"
    s "strings"
)
//We alias fmt.Println to a shorter name as we’ll use it a lot below
var p = fmt.Println

func main() {
	//	these are functions from the package, not methods on the string object itself
    p("Contains:  ", s.Contains("test", "es"))
    p("Count:     ", s.Count("test", "t"))
    p("HasPrefix: ", s.HasPrefix("test", "te"))
    p("HasSuffix: ", s.HasSuffix("test", "st"))
    p("Index:     ", s.Index("test", "e"))
    p("Join:      ", s.Join([]string{"a", "b"}, "-"))
    p("Repeat:    ", s.Repeat("a", 5))
    p("Replace:   ", s.Replace("foo", "o", "0", -1))
    p("Replace:   ", s.Replace("foo", "o", "0", 1))
    p("Split:     ", s.Split("a-b-c-d-e", "-"))
    p("ToLower:   ", s.ToLower("TEST"))
    p("ToUpper:   ", s.ToUpper("test"))
    p()
//getting the length of a string in bytes and getting a byte by index
// len and indexing all work at the byte level
//If you’re working with potentially multi-byte characters 
//you’ll want to use encoding-aware operations. 
    p("Len: ", len("hello"))   //5
    p("Char:", "hello"[1])    //101
}

String Formatting

  • 基于printf进行format
package main

import (
    "fmt"
    "os"
)

type point struct {
    x, y int
}

func main() {

    p := point{1, 2}
    //打印结构体实例
    fmt.Printf("%v\n", p)  //{1 2}

    fmt.Printf("%+v\n", p) //{x:1 y:2}

//%#v prints a Go syntax representation of the value
//i.e. the source code snippet that would produce that value.
    fmt.Printf("%#v\n", p)  //main.point{x:1, y:2}

    //打印type
    fmt.Printf("%T\n", p)  //main.point

    fmt.Printf("%t\n", true) //true

//十进制
    fmt.Printf("%d\n", 123) //123
//二进制
    fmt.Printf("%b\n", 14) //1110
//character
    fmt.Printf("%c\n", 33) //!
//十六进制
    fmt.Printf("%x\n", 456) //1c8

    fmt.Printf("%f\n", 78.9) //78.900000

    fmt.Printf("%e\n", 123400000.0) //1.234000e+08
    fmt.Printf("%E\n", 123400000.0) //1.234000E+08

    fmt.Printf("%s\n", "\"string\"") //"string"
//To double-quote strings as in Go source, use %q.
    fmt.Printf("%q\n", "\"string\"")  //"\"string\""
//%x renders the string in base-16, with two output characters per byte of input
    fmt.Printf("%x\n", "hex this") //6865782074686973

    fmt.Printf("%p\n", &p) //0x42135100
/*    
|    12|   345|
|  1.20|  3.45|
|1.20  |3.45  |
|   foo|     b|
|foo   |b     |
*/
//By default the result will be right-justified and padded with spaces
    fmt.Printf("|%6d|%6d|\n", 12, 345)
//6.2的6代表总宽度,2代表小数位数
    fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
//-表示靠左对齐
    fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)

    fmt.Printf("|%6s|%6s|\n", "foo", "b")

    fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
//Printf prints the formatted string to os.Stdout
//Sprintf formats and returns a string,但不打印出来
    s := fmt.Sprintf("a %s", "string")
    fmt.Println(s)   //a string
//format+print to io.Writers other than os.Stdout using Fprintf
    fmt.Fprintf(os.Stderr, "an %s\n", "error") //an error
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值