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 언뜻보기에 이것은 매우 일반적인 OOP 질문처럼 보이지만,이 언어를 사용할 때 모범 사례를 안내 할 스위프트 관련 기능을 알고 싶습니다.
답변
그것은 대부분 스타일의 문제인 것 같습니다. 나는 속성 을 사용하는 것을 강력히 선호 합니다 : 속성; 얻을 수있는 간단한 값을 의미합니다. 나는 실제 작업을 할 때 기능 (또는 방법)을 사용 합니다 . 디스크 나 데이터베이스에서 무언가를 계산하거나 읽어야 할 수도 있습니다.이 경우 간단한 값만 반환되는 경우에도 함수를 사용합니다. 이렇게하면 호출이 저렴한 지 (속성) 비용이 많이 드는지 (함수) 쉽게 확인할 수 있습니다.
Apple이 몇 가지 Swift 코딩 규칙을 게시하면 더 명확해질 것입니다.
답변
글쎄, 당신은 Kotlin의 조언 https://kotlinlang.org/docs/reference/coding-conventions.html#functions-vs-properties를 적용 할 수 있습니다 .
경우에 따라 인수가없는 함수는 읽기 전용 속성과 교환 할 수 있습니다. 의미는 비슷하지만 서로 선호하는시기에 대한 몇 가지 스타일 규칙이 있습니다.
기본 알고리즘이 다음과 같은 경우 함수보다 속성을 선호합니다.
- 던지지 않는다
- 복잡성은 계산하기가 저렴합니다 (또는 첫 번째 실행에서 계산 됨).
- 호출에 대해 동일한 결과를 반환합니다.
답변
일반적으로 계산 된 속성 대 메소드에 대한 질문은 어렵고 주관적이지만 현재 Swift의 경우 속성보다 메소드를 선호하는 중요한 주장이 하나 있습니다. 속성에 맞지 않는 순수한 함수로 Swift의 메서드를 사용할 수 있습니다 (Swift 2.0 베타 기준). 이것은 기능적 구성에 참여할 수 있기 때문에 메소드를 훨씬 더 강력하고 유용하게 만듭니다.
func fflat<A, R>(f: (A) -> () -> (R)) -> (A) -> (R) {
return { f($0)() }
}
func fnot<A>(f: (A) -> Bool) -> (A) -> (Bool) {
return { !f($0) }
}
extension String {
func isEmptyAsFunc() -> Bool {
return isEmpty
}
}
let strings = ["Hello", "", "world"]
strings.filter(fnot(fflat(String.isEmptyAsFunc)))
답변
런타임이 동일하기 때문에이 질문은 Objective-C에도 적용됩니다. 나는 당신이 얻는 속성으로
- 하위 클래스에 setter를 추가하여 속성을 만들 가능성
readwrite
didSet
변경 알림 을 위해 KVO /를 사용하는 기능- 보다 일반적으로 키 경로를 예상하는 메소드에 속성을 전달할 수 있습니다 (예 : 가져 오기 요청 정렬)
Swift에 특정한 것에 관해서는 제가 가진 유일한 예 @lazy
는 속성에 사용할 수 있다는 것 입니다.
답변
차이점이 있습니다. 속성을 사용하면 결국이를 재정의하고 하위 클래스에서 읽기 / 쓰기로 만들 수 있습니다.
답변
읽기 전용의 경우, 선언을 삭제 하면 인스턴스 의 상태 를 구성하는 수량과 단순히 함수 인 수량 간의 구분이 모호해 지기 때문에 계산 된 속성이 메서드와 의미 적으로 동일하다고 간주 되어서는 안됩니다 . 상태. 호출 사이트에서 타이핑 을 저장 하지만 코드의 명확성을 잃을 위험이 있습니다.func
()
간단한 예로 다음 벡터 유형을 고려하십시오.
struct Vector {
let x, y: Double
func length() -> Double {
return sqrt(x*x + y*y)
}
}
길이를 메서드로 선언하면 x
and에 의존하는 상태의 함수임을 분명히 알 수 y
있습니다.
반면 length
에 계산 된 속성 으로 표현한다면
struct VectorWithLengthAsProperty {
let x, y: Double
var length: Double {
return sqrt(x*x + y*y)
}
}
당신의 인스턴스에 IDE에서 탭 완성 점 때 다음 VectorWithLengthAsProperty
, 그것은 것처럼 보일 것이다 x
, y
, length
개념적으로 잘못 동등한에 등록했다.
답변
일반 함수보다 계산 된 속성을 선호하는 상황이 있습니다. 예 : 사람의 전체 이름을 반환합니다. 이름과 성을 이미 알고 있습니다. 따라서 실제로 fullName
속성은 함수가 아닌 속성입니다. 이 경우 계산 된 속성입니다 (전체 이름을 설정할 수 없기 때문에 이름과 성을 사용하여 추출 할 수 있습니다)
class Person{
let firstName: String
let lastName: String
init(firstName: String, lastName: String){
self.firstName = firstName
self.lastName = lastName
}
var fullName :String{
return firstName+" "+lastName
}
}
let william = Person(firstName: "William", lastName: "Kinaan")
william.fullName //William Kinaan