Swift-style-guide: Функции против методов

Созданный на 6 июл. 2015  ·  26Комментарии  ·  Источник: raywenderlich/swift-style-guide

В руководстве должно быть четко указано, как правильно использовать функцию и метод при написании. Взглянув на документы Apple Swift Programming Language, можно сказать что-то вроде:

Метод - это функция, связанная с классом, структурой или перечислением. Это касается как методов экземпляра, так и методов типа. С другой стороны, функция объявляется в глобальной области видимости и не принадлежит ни к какому типу.

будет достаточно.

Самый полезный комментарий

Как насчет чего-то вроде этого:

Методы и бесплатные функции

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

Предпочтительный

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

Не рекомендуется

let sorted = mergeSort(items)
launch(&rocket)

Исключения бесплатных функций

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

Все 26 Комментарий

Я также видел функции, называемые «бесплатными функциями». Я предполагаю, что «свободный» означает «не связанный ни с каким объектом».

У функций в Swift больше вариантов области действия, чем у типов и глобальных.

Я просто предположил, что обычные методы в Objective-C теперь упоминаются как functiona в Swift . Во всех материалах, которые я читал в терминах форумов, блогов, руководств и т. Д., Они упоминаются просто как functions , даже если они принадлежат классу или перечислению.

@mitchellporter В собственных документах Apple четко указано, когда что-то следует называть функцией или методом, согласно приведенной выше цитате.

Учебники на raywenderlich.com также соответствуют рекомендациям Apple, поэтому их следует включить в руководство по стилю.

В Objective-C есть как функции, так и методы; не все - метод. 😉

@micpringle Имеет смысл, но, клянусь, я читал много материалов, где они просто называют это function даже если он принадлежит классу. Я предполагаю, что я не единственный, кто всегда использует function , будет интересно посмотреть, изменится ли это в будущем.

Являются ли «функции» внутри методов «вложенными методами»?
Как называются функции внутри замыканий или другие не-функции?

struct Struct {
   let closure = {
      func whoAmI() {}
   }

   var any: Any? {
      func jeanValjean() {}
      return nil
   }
}

Я думаю, что они были бы классифицированы как анонимные функции (IMO), поскольку технически они не «принадлежат» ничему, существуют только в этой конкретной области и не могут быть доступны извне.

Я не думаю, что здесь правильное название «анонимная функция» - это обычно относится к закрытию.

Я бы назвал их «вложенными функциями»: «функциями», потому что это функции, а не методы, прикрепленные к именованному типу или экземпляру. И «вложенные», потому что ... они вложенные! Возможно, «ограниченные функции», но это не так ясно.

Извините, я не осознавал, что закрытия также называются анонимными функциями. :]

Вложенные функции мне нравятся. Я согласен, что область видимости не совсем правильная.

Я думаю, что «вложенные функции» внутри чего-либо, будь то метод или нет, в обозримом будущем кажется достаточно ясным.

И хотя я действительно думаю, что вложенные функции, имеющие имена, делают их «несимметричными», мне неясно, что именно «анонимно», однако, когда дело доходит до замыканий, особенно сохраненных, неизменяемых, которые очень похожи на функции. Я склоняюсь к тому, чтобы верить, что сохраненная функция действительно анонимна, но закрытие, которое ее фиксирует, и, возможно, какое-то состояние, - это то, что имеет имя. Так учат в C #, где лямбда-синтаксис - это сокращение для создания того, что он называет делегатом.
https://msdn.microsoft.com/en-us/library/system.delegate (v = vs.110) .aspx

func nonymous() {
   func nonymous() {}
}

let anonymouses: [() -> ()] = [].map
{$0} // This "transform" is also anonymous.

let unlcearToMeWhetherNonymous = {}

Это тонкий момент и, возможно, даже спорный, если вы перейдете к недрам Swift и все останется таким же, но объявление чего-то с помощью func определенно дает этому объекту имя. Напротив, закрытие - это просто какой-то блок кода без имени. Вы, конечно, можете присвоить его переменной или константе, но это просто сохранение указателя на вещь.

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

Как насчет чего-то вроде этого:

Методы и бесплатные функции

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

Предпочтительный

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

Не рекомендуется

let sorted = mergeSort(items)
launch(&rocket)

Исключения бесплатных функций

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

Касательно,

Исключения бесплатных функций

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

«Кажется естественным» довольно неоднозначно и субъективно.

Можем ли мы пояснить, что мы здесь имеем в виду?

Кроме того, и zip и max также пострадают от проблемы // hard to discover вы подняли в PR.

ИМХО, мне кажется, что zip - это неудобный пример. Проблемы, которые у меня есть с этим:

  • Что это на самом деле _doing_? Объединение a и b ? Каким-то образом сжимать a и b ? Что-то другое? Без дополнительного контекста это трудно понять.

Вместо

Бесплатные функции менее распространены, но имеют смысл, когда операция не связана тесно с конкретным типом или экземпляром.

Как насчет этого?

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

Бесплатные функции наиболее подходят, когда они не связаны с каким-либо конкретным типом или экземпляром.

Я снова открываю этот вопрос, чтобы продолжить обсуждение Free Function Exceptions .

Что ж, это стандартная библиотечная функция. Он имеет приоритет в таких языках, как R, Python, C #, C ++. (Через boost).

Что ж, это стандартная библиотечная функция.

Действительно? В iOS не пользовался ... * смущенно *

Я проверю ... Если это широко понимается / используется на iOS, возможно, мое беспокойство здесь неуместно ...

Мне нравится ваше многословие ... Я не хочу отказываться от примера с zip. (PS: У команды RW Swift устав больше (или меньше), чем у iOS.)

У команды RW Swift устав больше (или меньше), чем у iOS.

👍 Верно. ;]

Изучив, что делает zip , я оставлю его в качестве примера. 👍

Приношу свои извинения за мой опыт Swift-новичка здесь. 😉

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

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

Максимум

let max = Swift.max(0, 1, 2)
let maxElement = [0, 1, 2].maxElement()!

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

застегивать
В C # zip реализован как эквивалент метода расширения протокола Swift . Не думаю, что это лучше, но это пример того, как обращаться с zip другому.

В Swift zip - это то же самое, что и инициализатор для Zip2Sequence . Было бы неплохо иметь способ представить заархивированную последовательность с переменным количеством входных последовательностей, но пока это не произойдет, я думаю, что использование инициализатора напрямую - это нормально.

zip([1...3], ["a"..."c"])
Zip2Sequence([1...3], ["a"..."c"])

операторы
Подавляющее большинство бесплатных функций, которые я написал на Swift, являются операторами. Я видел, как Крис Латтнер и Джо Грофф предполагали, что в будущем операторы можно будет определять в типах, а-ля C #, поэтому операторы также могут следовать любым выбранным соглашениям для других функций. Их текущая реализация как «только бесплатные функции», вероятно, не должна использоваться в качестве руководства.

операторы
Подавляющее большинство бесплатных функций, которые я написал на Swift, являются операторами. Я видел, как Крис Латтнер и Джо Грофф предполагали, что в будущем операторы можно будет определять в типах, а-ля C # ...

Да, скорее всего, это направление, в котором Swift будет двигаться в будущем. Как вы упомянули, вот довольно недавнее предложение Криса Латтнера.

Это особенно характерно для таких протоколов, как Equatable , которые, согласно нашим рекомендациям по расширению, по сути _ требуют_ создания пустого расширения. Это в лучшем случае неловко. 😞

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

Спасибо за комментарии @ Jessy-!

Некоторые примечания:

Я думаю, что maxElement() объявлен методом, потому что это не O (1), что может удивить некоторых пользователей. Если вы реализуете свойство, отличное от O (1), оно должно быть четко задокументировано. (В руководствах по RW мы можем позволить себе роскошь, поскольку весь код находится в открытом доступе, поэтому нам не нужно беспокоиться об этом в такой степени или применять его в качестве руководства по стилю.)

С другой стороны, некоторые формы max<T: Comparable> имеют значение O (1) и могут быть специализированы для использования преимуществ оборудования. (Я предполагаю, что именно поэтому существует версия с двумя параметрами в дополнение к версии с переменным числом аргументов, хотя я этого не подтверждал.)

В любом случае, я думаю, мы все согласны с тем, что бесплатные функции следует использовать с осторожностью, но я бы выступил против _ Never_. Используемые примеры взяты из стандартной библиотеки. Предложений по удалению функции zip из стандартной библиотеки я не встречал. Есть ли возражения против специфики переформулировки @ JRG-Developer или текущего объединенного запроса на перенос по модулю этой переформулировки?

Не стесняйтесь открывать снова, если считаете, что есть что-то еще, что нужно обсудить. (Слито с веткой обновления.)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

rwenderlich picture rwenderlich  ·  29Комментарии

sima-11 picture sima-11  ·  5Комментарии

jrturton picture jrturton  ·  3Комментарии

luki picture luki  ·  3Комментарии

rayfix picture rayfix  ·  3Комментарии