Несмотря на этот другой ответ , в котором содержатся рекомендации относительно правильного нарезки для использования пакета sort
, я добавил этот ответ, чтобы дать более подробное описание некоторых дальнейших проблем с кодом, который вы опубликовали,Я надеюсь, что это поможет вам понять язык Go.
Введение в ломтики
Я беру на себя обязательство, что функция сортировки требует массивов без известного размера [sic]
Как другие сказали , это не терминология для описания этой концепции в Go.Все массивы Go имеют фиксированный размер, как определено языковой спецификацией .Как вы знаете, массивы имеют тип [N]T
для массива, который содержит некоторое неотрицательное число N
элементов типа T
.Это исправлено во время компиляции и никогда не изменяется во время выполнения вашей программы.
«Массивы без известного размера» наиболее близко соответствуют слайсам .Срезы - это различные типы в Go, которые позволяют представлять последовательности данных определенного типа, где их длина динамически управляется средой выполнения Go.Они относятся к типу []T
для элементов типа T
.В частности, их размер не является частью определения типа и может изменяться во время выполнения.Для некоторой переменной среза x []T
реализация обеспечивает:
- внутренний резервный массив аналогичного элементарного типа, где реализация управляет выделением памяти и расширением массива при увеличении длины среза
- его длина
len(x)
- обозначает количество элементов, которые в настоящее время содержит срез - его емкость
cap(x)
- общая длина среза плюс дополнительный размер подложкимассив, который может выходить за пределы длины из-за операций среза, ограничивающих представление массива или большего массива, выделяемого средой выполнения, чтобы можно было добавлять в элемент больше элементов.
См. Tour of Go и языковая спецификация на ломтиках для получения более подробной информации.
Решение проблемы с кодом
Как отмечено выше, срезы различного типа для массивов , поэтому вы не можете использовать что-то типа [N]T
для некоторых N
и T
, где некоторыетребуется вещь типа []T
.
sort.Ints
сортирует срез целых чисел на месте - он имеет сигнатуру типа func Ints(a []int)
.Ваш вызов sort.Ints(x[i])
индексирует массив x
по индексу i
, который возвращает массив типа [3]int
.Это несовместимо с функцией сортировки и приводит к ошибке времени компиляции, которую вы наблюдаете.
Чтобы получить срез из массива, вы используете выражение среза .Такие выражения позволяют использовать массивы, срезы и некоторые другие типы для создания новых срезов.
Выражения срезов задаются в виде a[low : high]
, где low
и high
- необязательные целые числа, предоставляющие индексы в основумассив или фрагмент, которые определяют диапазон, который нужно вернуть в новом фрагменте.Ссылка на спецификацию языка выше содержит больше деталей, которые я рекомендую вам прочитать;Достаточно сказать, что самое простое выражение среза a[:]
для некоторого массива или среза a
является синтаксическим сахаром, означающим a[0:len(a)-1]
, то есть преобразует массив / срез в срез той же длины.получить срез типа []int
из вашего многомерного массива, нарезав: x[i][:]
:
x[i]
возвращает массив типа [3]int
, как и раньше - разрезание возвращенного массива возвращает срез типа
[]int
, который совместим с sort.Ints
.
sort.Ints
не возвращает значение, и срезы не сравнимы
Даже если вы исправите эти проблемы с помощью своего кода, остаются следующие проблемы со следующей строкой:
t := sort.Ints(x[i]) == []int{1, 2, 3}
sort.Ints
сортирует на месте ;он не возвращает значение, поэтому проверка на равенство не имеет смысла. sort.Ints
работает на срезах, которые не сравнимы.Невозможно вызвать A == B
, где A
или B
является срезом, если только A
или B
не является специальным идентификатором nil
.Это тонкий момент, который описан в спецификации языка .(Помимо: прочитайте эту страницу, так как вы заметите, что массивы сопоставимы.)
Поскольку вы не можете сравнивать фрагменты напрямую, используя оператор равенства ==
, проверяя поэлементное равенствоиз срезов требуется:
- Срезы должны быть одинаковой длины (разная длина означает, что один срез имеет больше элементов, чем другой)
- Элементы в каждом индексе одного среза идентичны другимломтики.
(я игнорирую тот факт, что один ломтик может иметь разную емкость по отношению к другому, так как мы заботимся только о поэлементном равенстве.)
Это можно проверитьциклически проходя по одному из слайсов и проверяя элементы в каждом индексе, совпадающие по тому же индексу в другом слайсе.Этот пример кода предоставляет пример этого ( детская площадка ):
package main
import (
"fmt"
)
func CheckEquality(a, b []int) bool {
// Slices of dissimilar length are not equal
if len(a) != len(b) {
return false
}
for i, el := range a {
if b[i] != el {
return false
}
}
return true
}
func main() {
var mySlice = []int{1, 2, 3, 4, 5}
var mySlice2 = []int{1, 2, 3, 4, 5} // same as mySlice
var otherSlice = []int{5, 6, 7, 8, 9} // dissimilar slice
var longSlice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(CheckEquality(mySlice, mySlice2)) // Expect true
fmt.Println(CheckEquality(mySlice, otherSlice)) // Expect false
fmt.Println(CheckEquality(mySlice, longSlice)) // Expect false
}