Здесь создается какой-то конструктор?

В одном из примеров сортировки они используют следующий код:

package main

import (
 "fmt"
 "sort"
)

type Person struct {
 Name string
 Age int
}

func (p Person) String() string {
 return fmt.Sprintf("%s: %d", p.Name, p.Age)
}

// ByAge implements sort.Interface for []Person based on
// the Age field.
type ByAge []Person

func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

func main() {
 people := []Person{
 {"Bob", 31},
 {"John", 42},
 {"Michael", 17},
 {"Jenny", 26},
 }

 fmt.Println(people)
 sort.Sort(ByAge(people))
 fmt.Println(people)

}

Строка с сортировкой немного запутанна для меня:

sort.Sort(ByAge(people))

Создает ли ByAge (люди) какой-то конструктор, который копирует массив, который передается? Я не уверен, что понимаю, как новый тип ByAge имеет доступ к элементам в противном случае.

1 ответ

Синтаксис foo(expr) где foo - тип, а expr - преобразование типа, как описано в спецификации:

<h2> Конверсии</h2>

Преобразования представляют собой выражения вида <code>T(x)</code> где <code>T</code> - тип, а <code>x</code> - выражение, которое можно преобразовать в тип <code>T</code>

Conversion = Type "(" Expression [ "," ] ")" . </pre> <p> Если тип начинается с оператора <code>*</code> или <code> <-</code>, или если тип начинается с ключевого слова <code>func </code> и не имеет списка результатов, он должен быть заключен в скобки, когда необходимо, чтобы избежать двусмысленности:

*Point(p) // same as *(Point(p)) (*Point)(p) // p is converted to *Point <-chan int(c) // same as <-(chan int(c)) (<-chan int)(c) // c is converted to <-chan int func()(x) // function signature func() x (func())(x) // x is converted to func() (func() int)(x) // x is converted to func() int func() int(x) // x is converted to func() int (unambiguous) </pre> <p> Постоянное значение <code>x</code> может быть преобразовано в тип <code>T</code> в любом из этих случаев:

<ul> <li> <code>x</code> представляется в виде значения типа <code>T</code></li> <li> <code>x</code> - константа с плавающей запятой, <code>T</code> - тип с плавающей запятой, и <code>x</code> представляется в виде значения типа <code>T</code> после округления с использованием правил IEEE 754 round-to-even. Константа <code>T(x)</code> является округлым значением.</li> <li> <code>x</code> - целочисленная константа, а <code>T</code> - строковый тип. В этом случае применяется то же правило, что и для непостоянного <code>x</code>.</li> </ul>

Преобразование константы приводит к типичной константе.

****(iota) // iota value of type **** float32(2.718281828) // 2.718281828 of type float32 complex128(1) // 1.0 + 0.0i of type complex128 float32(0.49999999) // 0.5 of type float32 string('x') // "x" of type string string(0x266c) // "♬" of type string MyString("foo" + "bar") // "foobar" of type MyString string([]byte{'a'}) // not a constant: []byte{'a'} is not a constant (*int)(nil) // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type int(1.2) // illegal: 1.2 cannot be represented as an int string(65.0) // illegal: 65.0 is not an integer constant </pre> <p> Непостоянное значение x может быть преобразовано в тип T в любом из этих случаев:

<ul> <li> <code>x</code> присваивается <code>T</code></li> <li> <code>x</code> type и <code>T</code> имеют одинаковые базовые типы.</li> <li> <code>x</code> type и <code>T</code> являются неназванными типами указателей, а их базовые типы указателей имеют одинаковые базовые типы.</li> <li> <code>x</code> type и <code>T</code> являются целыми или с плавающей запятой. <code>x</code> и <code>T</code> являются сложными типами.</li> <li> <code>x</code> - целое число или фрагмент байтов или рун, а <code>T</code> - строковый тип.</li> <li> <code>x</code> - строка, а <code>T</code> - фрагмент байтов или рун.</li> </ul>

Конкретные правила применяются к (непостоянным) преобразованиям между числовыми типами или к типу строк и из него. Эти преобразования могут изменить представление <code>x</code> и взять на себя затраты времени выполнения. Все другие преобразования меняют только тип, но не представление <code>x</code>.

Не существует лингвистического механизма для преобразования между указателями и целыми числами. Небезопасный пакет реализует эту функциональность в ограниченных условиях.

Дополнительную информацию см. на связанной странице.

licensed under cc by-sa 3.0 with attribution.