Почему некоторые выражения регистрируют результаты, а другие просто показывают количество итераций?

Я не очень часто использовал игровые площадки со Swift. В основном я использую его в проектах, поэтому я немного теряюсь в работе с игровыми площадками.

У меня есть этот тестовый код на небольшой игровой площадке:

let array = [7, 3, 4, 9, 2, 12, 5]
let firstSorted = array.sorted(<)
let secondSorted = sorted(array, <)
let thirdSorted = array.sorted { $0 < $1 }

Выходные данные, показанные справа, показывают выходные данные отсортированного массива рядом с firstSorted и secondSorted. Однако вывод рядом с ThirdSorted просто говорит (15 раз).

Почему? И как мне увидеть вывод, не добавляя отдельную команду println для регистрации вывода?

Третья форма имеет завершающее замыкание с параметрами, определяемыми их позициями.

Два других — еще более короткая форма, в которой используется только оператор сравнения, который совпадает с сигнатурой необходимого замыкания.

Еще вопрос: (на этот раз о языке, а не о площадках) Почему работают обе формы sorted(array, <) и array.sorted(<)? Первая — это глобальная функция, которая принимает 2 параметра, а вторая форма — это метод класса Array.


person Duncan C    schedule 14.04.2015    source источник


Ответы (1)


Это потому, что замыкание, которое вы передаете в sorted, вызывается sorted для сравнения 13 элементов при сортировке массива плюс вызов самого sorted. Всякий раз, когда написанная вами строка кода запускается на игровой площадке, она отображает либо результат выражения, либо количество. Поскольку одна и та же строка оценивается несколько раз, среда IDE не может показать все, поэтому показывает только количество.

Если разбить его на несколько строк, можно увидеть результат sorted, а также результаты 13 оценок $0 < $1:

Изображение, показывающее 13 казней плюс результат

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

Что касается второго вопроса: глобальная версия sorted с двумя аргументами является более общей. Он сортирует любую последовательность:

// they should probably rename this placeholder to S...
func sorted<C : SequenceType>
  (source: C, isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool) 
  -> [C.Generator.Element]

поэтому вы можете передать все, что соответствует SequenceType:

// results in [4,3,2,1,0]
sorted(0..<5, >)  

// results in [(3,"bob"),(2,"fred")] because dictionary’s 
// SequenceType representation is unordered pairs
sorted([2:"fred",3:"bob"]) { $0.1 < $1.1 }

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

func sorted<C : SequenceType where C.Generator.Element : Comparable>
  (source: C) -> [C.Generator.Element]
person Airspeed Velocity    schedule 14.04.2015
comment
Еще одна вещь, которую я забыл упомянуть — теоретически версия sorted для члена может быть быстрее, поскольку она может знать больше о своем вводе, поэтому, вероятно, ее следует предпочесть, когда вы можете ее использовать. - person Airspeed Velocity; 15.04.2015