Monthly Archives: November 2014

Многоликие функции Swift

Русский перевод статьи Natasha Murashev The Many Faces of Swift Functions.

Хотя у Objective-C синтаксис выглядит несколько странно,  по сравнению с другими языками программирования, синтаксис метода – прост и понятен. Вот небольшой экскурс в прошлое

+ (void)mySimpleMethod
{
    // метод "класса"
    // нет параметров
    // нет возвращаемых значений
}

- (NSString *)myMethodNameWithParameter1:(NSString *)param1 parameter2:(NSNumber *)param2
{
    // метод "экземпляра"
    // один параметр - типа NSString указатель,
    // второй параметр - типа NSNumber указатель
    // должен вернуть значение типа NSString указатель
    return @"hello, world!";
}

В противоположность этому, синтаксис  Swift выглядит в большинстве случаев также, как и в других языках программирования, но временами он может быть более сложным и запутанным, чем Objective-C.

Continue reading

Какие функции вызывает Swift? Часть 5: Range против Interval.

Это русский перевод статьи airspeedvelocity Which function does Swift call? Part 5: Range vs Interval

Это часть 5 из серии постов о том, как Swift разрешает “неоднозначность” в “перегруженных” функциях. Часть 1 можно найти  здесь (русский перевод – здесь). В предыдущей статье (русский перевод – здесь), мы рассматривали как управлять  generics.

И наконец …

Теперь, когда мы рассмотрели как подбираются  generics, мы можем наконец ответить на первоначальный вопрос – как мы получаем тип  Range по умолчанию для выражения 1...5 ? Вот образец кода:

// r будет иметь тип Range<Int>
let r = 1...5

// если вы хотите такой тип ClosedInterval<Int>, то вам
// нужно задать тип явно:
let integer_interval: ClosedInterval = 1...5

// если вам нужен тип Doubles, то нет необходимости
// декларировать тип явно.
// floatingpoint_interval is a ClosedInterval<Double>
let floatingpoint_interval = 1.0...5.0

Функция, соответствующая infix оператору  ...  , определяется трижды в стандартной библиотеке со следующими сигнатурами:

func ...<T : Comparable>
  (start: T, end: T) -> ClosedInterval<T>

func ...<Pos : ForwardIndexType>
  (minimum: Pos, maximum: Pos) -> Range<Pos>

func ...<Pos : ForwardIndexType where Pos : Comparable>;
  (start: Pos, end: Pos) -> Range<Pos>

Первые две – очень простые. Они обе generic, у них единственная generic метка-заполнитель (placeholder), которая ограничена единственным протоколом. Нет преимущества у одного ограничения перед другим.

Оба протокола Comparable и ForwardIndexType происходят из протокола Equatable, но ни один из них не происходит от другого. Если мы оставим только эти две функции, то мы получим ошибку “неоднозначности” –ambiguous call error.

Но есть третья функция, которая и заставляет Swift выбрать Range , а не  ClosedInterval. В этой функции, Pos ограничивается не только ForwardIndexType, но и Comparable. Ограничение двумя протоколами выигрывает у ограничения с одним, так что при “перегрузке” будет выбрана эта функция.

Continue reading

Какие функции вызывает Swift? Часть 4: Generics.

Это русский перевод статьи airspeedvelocity “Which function does Swift call? Part 4: Generics”.

Это 4 часть из серии статей, посвященных тому, как выбираются “перегруженные” (overloaded) функции в Swift. Часть 1 рассматривает “перегрузку” (overloading) по типу возвращаемого значения, часть 2 о том, как различные функции с простым одним аргументом выбираются по принципу “наиболее подходящей” функции, и часть 3 раскрывает этот принцип более детально в плане протоколов.

Мы начали серию статей с вопроса, почему мы получаем тип Range для 1…5 вместо типа  ClosedInterval? Сегодня мы разберем как  generics вписываются в иерархию “наиболее подходящей” функции, и у нас наконец будет достаточно информации для ответа на вопрос.

Generics – это более низкий приоритет

Continue reading

Какие функции вызывает Swift? Часть 3: Композиция протоколов.

Это русский перевод статьи airspeedvelocity “Which functions does Swift call? Part 3: Protocol Composion”

В предыдущих статьях мы исследовали,  как функции Swift могут быть “перегружены” только по возвращаемому типу, и как Swift выбирает между различными возможными “перегрузками” с помощью механизма “наилучшего соответствия” ( best-match mechanism).

Эти исследования мы провели с целью выяснения причины, почему  1…5 возвращает тип Range а не тип ClosedInterval. И для понимания этого нам нужно рассмотреть как generics работают с критериями “наилучшего соответствия”.

Но прежде чем мы этим займемся, короткое шаг в сторону для исследования композиции протоколов.

Протоколы могут объединяться путем расположения 0 или более протоколов между угловыми скобками в предложении  protocol<> . Книга Apple Swift говорит следующее:

ЗАМЕЧАНИЕ
Композиция протоколов не определяет новый , постоянный тип протокола. А определяет временный локальный протокол,  у которого есть комбинированнык требования всех протоколов в композиции.

Читая это, можно подумать, что декларирование протокола protocol<P,Q> подобно декларированию анонимного протокола Tmp: P, Q { }, и Tmp можно использовать не давая ему имени. Но означает это не совсем то, и способ, который бы высветил разницу состоит в декларировании функций, которые имеют аргументы, декларированные с протоколом.

Continue reading

Какие функции вызывает Swift? Часть 2: Единственные аргументы.

Это русский перевод статьи airspeedvelocity 

Which function does Swift call? Part 2: Single Arguments

В предыдущей статье мы видели, что Swift разрешает “перегрузку” ( overloading ) функций просто по типу возвращаемого значения. С такого типа “перегрузками” явное объявление типа говорит Swift какую функцию вы хотите вызвать:

// r будет иметь тип Range<Int>
let r = 1...5

// если вы хотите тип ClosedInterval<Int>, вам следует
// явно указать:
let integer_interval: ClosedInterval = 1...5

Но все это не объясняет, почему мы получаем тип Range по умолчанию, хотя не указывали, какой тип возвращаемого значения мы хотим. Для ответа на этот вопрос нам следует посмотреть на аргументы функции. И мы начнем с простейших функций, у которых один аргумент.

В противоположность возвращаемым значениям, функции с теми же самыми именами, но с различными типами своих аргументов не всегда нуждаются в явной “однозначности” ( disambiguation). Swift будет пытаться их выбрать наилучшим образом, основываясь на различных критериях “наилучшего соответствия”.

Согласно правилу “большого пальца”, Swift любит выбирать наиболее “специфическую” функцию, возможно, основываясь на передаваемых параметрах. Любимая вещь Swift, вещь, которая “бьет” все другие функции с “единственными” аргументами, это функция с аргументом точно такого типа как мы передаем при вызове.

Если Swift не находит функцию, которая имеет точно такой же тип, как мы передали при вызове, следующей предпочтительной опцией является наследуемый класс или протокол. Классы -“дети” или протоколы являются более предпочтительными чем “родители”.

Давайте посмотрим это в действии:

Continue reading

Какие функции вызывает Swift? Часть 1: Возвращаемые значения

Это русский перевод статьи airspeedvelocity

“Which function does Swift call? Part 1: Return Values “.

Тип данных ClosedInterval “стесняется”. Вам придется уговаривать его выйти из-за спины своего друга, Range.

// r будет иметь тип Range<Int>
let r = 1...5

// если вам нужен тип ClosedInterval<Int>, вам
// следует определить его явно:
let integer_interval: ClosedInterval = 1...5

// Но если вам нужен doubles, то нет необходимости
// декларировать его явно.
// floatingpoint_interval is a ClosedInterval<Double>
let floatingpoint_interval = 1.0...5.0

Начиная с  Swift 1.0 beta 5, Range поддерживается исключительно для представления диапазонов индексов в коллекции.

Если вы не работаете с индексами, тип ClosedInterval, возможно, это то, что вам нужно. У него есть методы, подобные contains, которые за фиксированное ( независящее от длины интервала ) время определяют, содержит ли интервал некоторое значение:

Continue reading

Swift код к статье “Парсинг вложенных JSON и массивов (Arrays) в Swift.”

В этом посте представлен Swift код, который сопровождал изучение и перевод статьи Tony DiPasquale  “Парсинг вложенных JSON  и массивов (Arrays) в Swift.” (перевод) – оригинал Parsing Embedded JSON and Arrays in Swift

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

Кроме того, хотелось бы отследить сам процесс превращения функции парсинга JSON-данных в Модель из тривиального  варианта в компактный  вариант “функциональных концепций”. В этой статье появление компактного варианта осложняется необходимостью доставать данные из “вложенных” JSON  структур и массивов. Посмотрим как эта задача решается с позиции Swift кода как на тестовых примерах, предложенных в самой статье, так и на двух наших контрольных данных.

Continue reading

Swift код к статье Tony DiPasquale “Реальный мир парсинга JSON в Swift”

В этом посте представлен Swift код, который сопровождал изучение и перевод статьи Tony DiPasquale  “Реальный мир парсинга JSON в Swift” (перевод) – оригинал Real World JSON Parsing with Swift .

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

Эксперименты с алгоритмами Тони ДеПаскуале проводились в Swift 1.1, и представлены в репозитории на Github, который включает в себя различные  Playground файлы и полноценное небольшое приложение для работы  с данными с сайта Flickr.com.

Continue reading