排序
自然排序
- 改变了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
}