# 11.7. 第一个例子：使用 Sorter 接口排序

``````func Sort(data Sorter) {
for pass := 1; pass < data.Len(); pass++ {
for i := 0;i < data.Len() - pass; i++ {
if data.Less(i+1, i) {
data.Swap(i, i + 1)
}
}
}
}``````

`Sort` 函数接收一个接口类型参数：`Sorter` ，它声明了这些方法：

``````type Sorter interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}``````

``````type IntArray []int
func (p IntArray) Len() int           { return len(p) }
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
func (p IntArray) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }``````

``````data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
a := sort.IntArray(data) //conversion to type IntArray from package sort
sort.Sort(a)``````

``````package sort

type Sorter interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}

func Sort(data Sorter) {
for pass := 1; pass < data.Len(); pass++ {
for i := 0; i < data.Len()-pass; i++ {
if data.Less(i+1, i) {
data.Swap(i, i+1)
}
}
}
}

func IsSorted(data Sorter) bool {
n := data.Len()
for i := n - 1; i > 0; i-- {
if data.Less(i, i-1) {
return false
}
}
return true
}

// Convenience types for common cases
type IntArray []int

func (p IntArray) Len() int           { return len(p) }
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
func (p IntArray) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

type StringArray []string

func (p StringArray) Len() int           { return len(p) }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }
func (p StringArray) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

// Convenience wrappers for common cases
func SortInts(a []int)       { Sort(IntArray(a)) }
func SortStrings(a []string) { Sort(StringArray(a)) }

func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)) }
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) }``````

``````package main

import (
"./sort"
"fmt"
)

func ints() {
data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
a := sort.IntArray(data) //conversion to type IntArray
sort.Sort(a)
if !sort.IsSorted(a) {
panic("fails")
}
fmt.Printf("The sorted array is: %v\n", a)
}

func strings() {
data := []string{"monday", "friday", "tuesday", "wednesday", "sunday", "thursday", "", "saturday"}
a := sort.StringArray(data)
sort.Sort(a)
if !sort.IsSorted(a) {
panic("fail")
}
fmt.Printf("The sorted array is: %v\n", a)
}

type day struct {
num       int
shortName string
longName  string
}

type dayArray struct {
data []*day
}

func (p *dayArray) Len() int           { return len(p.data) }
func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num }
func (p *dayArray) Swap(i, j int)      { p.data[i], p.data[j] = p.data[j], p.data[i] }

func days() {
Sunday    := day{0, "SUN", "Sunday"}
Monday    := day{1, "MON", "Monday"}
Tuesday   := day{2, "TUE", "Tuesday"}
Wednesday := day{3, "WED", "Wednesday"}
Thursday  := day{4, "THU", "Thursday"}
Friday    := day{5, "FRI", "Friday"}
Saturday  := day{6, "SAT", "Saturday"}
data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday}
a := dayArray{data}
sort.Sort(&a)
if !sort.IsSorted(&a) {
panic("fail")
}
for _, d := range data {
fmt.Printf("%s ", d.longName)
}
fmt.Printf("\n")
}

func main() {
ints()
strings()
days()
}``````

``````The sorted array is: [-5467984 -784 0 0 42 59 74 238 905 959 7586 7586 9845]
The sorted array is: [ friday monday saturday sunday thursday tuesday wednesday]
Sunday Monday Tuesday Wednesday Thursday Friday Saturday ``````

`panic("fail")` 用于停止处于在非正常情况下的程序（详细请参考 第13章），当然也可以先打印一条信息，然后调用 `os.Exit(1)` 来停止程序。

``````type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}``````

a). 继续扩展程序，定义类型 `Triangle`，让它实现 `AreaInterface` 接口。通过计算一个特定三角形的面积来进行测试（三角形面积=0.5 (底 高)）

b). 定义一个新接口 `PeriInterface`，它有一个 `Perimeter` 方法。让 `Square` 实现这个接口，并通过一个 `Square` 示例来测试它。

• `NewFloat64Array()`：创建一个包含25个元素的数组变量（参考10.2）
• `List()`：返回数组格式化后的字符串，并在 `String()` 方法中调用它，这样就不用显式地调用 `List()` 来打印数组（参考10.7）
• `Fill()`：创建一个包含10个随机浮点数的数组（参考4.5.2.6）