Принятие как массива, так и ArraySlice как одного и того же параметра в Swift - PullRequest
0 голосов
/ 14 июля 2020

Я пишу функцию, которая принимает в качестве параметра как Array<Int>, так и ArraySlice<Int>. Функция полагается на сопоставимые элементы (на самом деле Int) и индексы с целочисленными индексами, что подразумевается как Array, так и ArraySlice. Мне удалось найти пересечение между этими двумя типами в RandomAccessCollection.

К сожалению, я не могу просто использовать RandomAccessCollection<Int>: (Ошибка следующая: «Невозможно выделить не-общий тип c 'RandomAccessCollection' "). Вместо этого мне пришлось сделать следующее длинное объявление:

func functionName<T>(
  arr: T
) -> T.Element where T: RandomAccessCollection, T.Element: Comparable, T.Index == Int {
  // implementation
}

Я хотел бы по возможности упростить объявление функции. В идеале хотелось бы сделать его настолько чистым, насколько это были бы принимающие массивы: func functionName(_ arr: [Int]) -> Int). Возможно ли это?

Основная причина для принятия обоих типов следующая: при написании алгоритма функция часто принимает массив, но ей нужно сделать рекурсивный вызов самой себе с помощью фрагмента массива. Поскольку некрасиво ограничивать publi c API функции до ArraySlice, вам придется либо возиться с универсальными шаблонами (как описано выше), либо создавать вложенную функцию, которая принимает фрагмент массива и вызывать его вместо этого (или создавать новый массив из фрагмента массива что тоже не кажется правильным). Оба варианта создают ненужную сложность для простой работы.

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Вы можете объявить его с помощью ArraySlice, не так ли?

func functionName<T: Comparable>(arr: ArraySlice<T>) -> T {
    
}

Затем для всего массива вы можете передать arr [0 .. ArraySlice имеет временную сложность O (1)

1 голос
/ 14 июля 2020

Создание ArraySlice из массива дешево - O (1), поэтому преобразуйте исходный массив в ArraySlice для первого вызова функции, а затем обработайте только ArraySlice s.

Вы также можете перегрузить метод, чтобы он принимал оба:

func functionName(arr: [Int]) -> Int {
   functionName(arr: arr[...])
}

func functionName(arr: ArraySlice<Int>) -> Int {
   // ...
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...