Во введении в сеанс Swift WWDC description
демонстрируется свойство только для чтения :
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description)
Есть ли какие-либо последствия для выбора вышеуказанного подхода вместо использования метода:
class Vehicle {
var numberOfWheels = 0
func description() -> String {
return "\(numberOfWheels) wheels"
}
}
let vehicle = Vehicle()
println(vehicle.description())
Мне кажется, что наиболее очевидными причинами, по которым вы выберете вычисляемое свойство только для чтения, являются:
- Семантика - в этом примере имеет смысл
description
быть свойством класса, а не действием, которое он выполняет. - Краткость / Четкость - предотвращает необходимость использования пустых скобок при получении значения.
Очевидно, что приведенный выше пример слишком прост, но есть ли другие веские причины выбрать один из них? Например, есть ли какие-то особенности функций или свойств, которые помогут вам решить, какие из них использовать?
NB. На первый взгляд это кажется довольно частым вопросом ООП, но я очень хочу знать о каких-либо специфических для Swift функциях, которые могли бы служить руководством для наилучшей практики использования этого языка.
methods
properties
semantics
swift
Стюарт
источник
источник
get {}
? Я этого не знал, спасибо!Ответы:
Мне кажется , что это в основном вопрос стиля: я сильно предпочитаю использовать свойства только для этого: свойства; означает простые значения, которые вы можете получить и / или установить. Я использую функции (или методы), когда выполняется реальная работа. Возможно, что-то нужно вычислить или прочитать с диска или из базы данных: в этом случае я использую функцию, даже если возвращается только простое значение. Таким образом, я могу легко увидеть, является ли вызов дешевым (свойства) или, возможно, дорогим (функции).
Мы, вероятно, получим больше ясности, когда Apple опубликует некоторые соглашения о кодировании Swift.
источник
Что ж, вы можете применить советы Котлина https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties .
источник
Хотя вопрос о вычисленных свойствах и методах в целом является сложным и субъективным, в настоящее время в случае Swift есть один важный аргумент в пользу предпочтения методов над свойствами. Вы можете использовать методы в Swift как чистые функции, что неверно для свойств (начиная с бета-версии Swift 2.0). Это делает методы намного более мощными и полезными, поскольку они могут участвовать в функциональной композиции.
источник
Поскольку среда выполнения такая же, этот вопрос относится и к Objective-C. Я бы сказал, со свойствами вы получаете
readwrite
didSet
для уведомлений об измененияхЧто касается чего-то особенного для Swift, единственный у меня пример - это то, что вы можете использовать
@lazy
для свойства.источник
Есть разница: если вы используете свойство, вы можете в конечном итоге переопределить его и сделать чтение / запись в подклассе.
источник
willSet
иdidSet
к базовому классу, не зная ничего о будущих производных классах, может обнаруживать изменения в переопределенном свойстве. Но с функциями, я думаю, ничего подобного нельзя.В случае только для чтения, вычисляемое свойство следует не считать семантический эквивалентно методой, даже если они ведут себя одинаково, потому что сбросив
func
декларацию стирает различие между величинами , которые включают состояние экземпляра и количеством , которые являются лишь функциями из штат. Вы экономите на вводе текста()
на сайте вызова, но рискуете потерять ясность в своем коде.В качестве тривиального примера рассмотрим следующий векторный тип:
Объявляя длину как метод, становится ясно, что это функция состояния, которое зависит только от
x
иy
.С другой стороны, если бы вы выразили
length
вычисленное свойствозатем, когда вы выполняете dot-tab-complete в своей среде IDE на экземпляре
VectorWithLengthAsProperty
, это будет выглядеть , как будтоx
,y
,length
были свойства на равных, что концептуально неверно.источник
Бывают ситуации, когда вы предпочитаете вычисляемое свойство обычным функциям. Например: возврат полного имени человека. Вы уже знаете имя и фамилию. Так что на самом деле
fullName
свойство - это свойство, а не функция. В данном случае это вычисляемое свойство (поскольку вы не можете установить полное имя, вы можете просто извлечь его, используя имя и фамилию)источник
С точки зрения производительности разницы нет. Как вы можете видеть в результате теста.
суть
main.swift
фрагмент кода:Вывод:
prop: 0.0380070209503174 func: 0.0350250005722046 prop: 0.371925950050354 func: 0.363085985183716 prop: 3.4023300409317 func: 3.38373708724976 prop: 33.5842199325562 func: 34.8433820009232 Program ended with exit code: 0
В диаграмме:
источник
Date()
не подходит для тестов, поскольку использует часы компьютера, которые автоматически обновляются операционной системой.mach_absolute_time
получит более надежные результаты.С семантической точки зрения вычисляемые свойства должны быть тесно связаны с внутренним состоянием объекта - если другие свойства не изменяются, то запрос вычисляемого свойства в разное время должен давать тот же результат (сопоставимый с помощью == или ===) - аналогично для вызова чистой функции для этого объекта.
С другой стороны, методы исходят из коробки с предположением, что мы не всегда можем получать одинаковые результаты, потому что Swift не имеет способа пометить функции как чистые. Кроме того, методы в ООП считаются действиями, а это означает, что их выполнение может привести к побочным эффектам. Если у метода нет побочных эффектов, его можно безопасно преобразовать в вычисляемое свойство.
Обратите внимание, что оба приведенных выше утверждения основаны исключительно на семантической перспективе, так как вычисленные свойства могут иметь побочные эффекты, которых мы не ожидаем, а методы - чистыми.
источник
Исторически описание является свойством NSObject, и многие ожидают, что оно останется таким же и в Swift. Добавление паренов после этого только добавит путаницы.
РЕДАКТИРОВАТЬ: после яростного отрицательного голосования я должен кое-что уточнить - если к нему обращаются через точечный синтаксис, это можно рассматривать как свойство. Неважно, что под капотом. Вы не можете получить доступ к обычным методам с точечным синтаксисом.
Кроме того, для вызова этого свойства не требовались лишние скобки, как в случае со Swift, что может привести к путанице.
источник
description
это обязательный метод поNSObject
протоколу, и поэтому в Objective-C возвращается использованием[myObject description]
. В любом случае это свойствоdescription
было просто надуманным примером - я ищу более общий ответ, применимый к любому настраиваемому свойству / функции.