go语言打怪通关之 ⌈排序⌋

排序

Go 的 sort 包实现了内置和用户自定义数据类型的排序功能,首先关注内置数据类型的排序。

package main

import "fmt"
import "sort"

func main() {

    // 排序方法是正对内置数据类型的;这里是一个字符串的例子。
    // 注意排序是原地更新的,所以他会改变给定的序列并且不返回
    // 一个新值。
    strs := []string{"c", "a", "b"}
    sort.Strings(strs)
    fmt.Println("Strings:", strs)

    // 一个 `int` 排序的例子。
    ints := []int{7, 2, 4}
    sort.Ints(ints)
    fmt.Println("Ints:   ", ints)

    // 我们也可以使用 `sort` 来检查一个序列是不是已经
    // 是排好序的。
    s := sort.IntsAreSorted(ints)
    fmt.Println("Sorted: ", s)
}

函数自定义排序

有时候我们想使用和集合的自然排序不同的方法对集合进行排序。例如,我们想按照字母的长度而不是首字母顺序对字符串排序。这里是一个 Go 自定义排序的例子。

package main

import "sort"
import "fmt"

// 为了在 Go 中使用自定义函数进行排序,我们需要一个对应的
// 类型。这里我们创建一个为内置 `[]string` 类型的别名的
// `ByLength` 类型,
type ByLength []string

// 我们在类型中实现了 `sort.Interface` 的 `Len`,`Less`
// 和 `Swap` 方法,这样我们就可以使用 `sort` 包的通用
// `Sort` 方法了,`Len` 和 `Swap` 通常在各个类型中都差
// 不多,`Less` 将控制实际的自定义排序逻辑。在我们的例
// 子中,我们想按字符串长度增加的顺序来排序,所以这里
// 使用了 `len(s[i])` 和 `len(s[j])`。
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])
}

// 一切都准备好了,我们现在可以通过将原始的 `fruits` 切片转型成 `ByLength` 来实现我们的自定排序了。然后对这个转型的切片使用 `sort.Sort` 方法。
func main() {
    fruits := []string{"peach", "banana", "kiwi"}
    sort.Sort(ByLength(fruits))
    fmt.Println(fruits)
}

Panic

panic 意味着有些出乎意料的错误发生。通常我们用它来表示程序正常运行中不应该出现的,或者我们没有处理好的错误。

package main

import "os"

func main() {

    // 我们将在真个网站中使用 panic 来检查预期外的错误。这个
    // 是唯一一个为 panic 准备的例子。
    panic("a problem")

    // panic 的一个基本用法就是在一个函数返回了错误值但是我们并不知道(或
    // 者不想)处理时终止运行。这里是一个在创建一个新文件时返回异常错误时的
    // `panic` 用法。
    _, err := os.Create("/tmp/file")
    if err != nil {
        panic(err)
    }
}

Defer

Defer 被用来确保一个函数调用在程序执行结束前执行,同样用来执行一些清理工作,defer 用在像其他语言中的 ensure 和 finally 用到的地方。

package main

import "fmt"
import "os"

// 假设我们想要创建一个文件,向它进行写操作,然后在结束
// 时关闭它。这里展示了如何通过 `defer` 来做到这一切。
func main() {

    // 在 `closeFile` 后得到一个文件对象,我们使用 defer
    // 通过 `closeFile` 来关闭这个文件。这会在封闭函数
    // (`main`)结束时执行,就是 `writeFile` 结束后。
    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")
    f.Close()
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海岸星的清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值