Swift 팀이 dev 포럼에 게시하여 두 번째 예제를 첫 번째 줄임말로 사용할 수있는 것이 좋을 것이라고 생각합니다.그러나, 나는 그것이 여전히 정말로 일반적인 함수라고 생각한다. 하나를 선언하는 것의 단축형인가?
어떻게 다릅니 까? 다른 대답이 지적한대로 Equatable
은 일반적으로 만 사용할 수 있습니다. 그러나 꼭 그렇게 할 필요는없는 예를 들어 봅시다. 방법이 있습니다 :이에서
func f<T: Printable>(t: T) {
// do some stuff
}
다른
:
func g(p: Printable) {
// do some stuff
}
의 차이는, f
가 무엇 이건, 컴파일시에 생성되는 함수의 가족을 정의 t
로 전달되는 유형 * Int
을 전달하면 마치 func f(t: Int) { … }
이라고 쓰여진 것처럼 보입니다. 당신이 Double
전달하는 경우, 그것은 *이 과도하게 단순화 func f(t: Double) { … }
를 작성하는 것과 같다 그러나 다른 한편으로는 ... 지금은 그것으로
를 이동 g
는 하나의 함수는은이며, 런타임은 Printable
프로토콜에 대한 참조 만 허용 할 수 있습니다.
실제로 차이는 거의 감지 할 수 없습니다. 다른 기능 f
내부의 t
를 전달하는 경우 예를 들어,이 같은 역할 :
그래서 예를 들면
func f(i: Int) {
// h doesn’t receive an Int
// but a Printable:
h(i as Printable)
}
:
func f<T: Printable>(t: T) {
println(sizeof(t))
}
f(1 as Int8) // prints 1
f(1 as Int64) // prints 8
: 당신은 비록 작은 방법의 차이를 볼 수 있습니다
func h(i: Int) {
println("An Int!")
}
func h(p: Printable) {
println("A Printable!")
}
func f<T: Printable>(t: T) {
h(t)
}
h(1) // prints "An Int!"
f(1) // prints "A Printable!"
가장 큰 차이점은 프로토콜이 아닌 실제 제네릭 형식을 반환 할 수 있다는 것입니다.
func f<T: Printable>(t: T) -> T {
return t
}
func g(p: Printable) -> Printable {
return p
}
let a = f(1) // a is an Int
let b = f([1]) // b is an [Int]
let c = g(1) // c is a Printable
let d = g([1]) // d is a Printable
이 마지막 예제는 관련 유형이있는 프로토콜을 일반적으로 만 사용할 수있는 이유를 이해하는 데 핵심적인 역할을합니다. 당신이 first
당신 자신의 구현 만들고 싶어한다고 가정
func first<C: CollectionType>(x: C) -> C.Generator.Element? {
if x.startIndex != x.endIndex {
return x[x.startIndex]
}
else {
return nil
}
}
first
는 일반적인 기능 및 CollectionType
프로토콜의 인수를받은 단지 일반 기능 아니었다면, 어떻게 무엇을 변화 할 수있을 것입니다 그것을 돌아왔다?
두 번째 스 니펫이 컴파일되지 않고 '프로토콜 Equatable은 일반 제약 조건으로 만 사용할 수 있습니다.'컴파일러 오류가 발생합니다. 음, 컴파일 할 수 있다는 것은 상당한 이점입니다, 그렇죠? ;) – siejkowski
저는 이것이 깊은 문제에 관한 훌륭한 질문이라고 생각합니다. 예, 두 번째 스 니펫은 컴파일되지 않습니다. 왜 안돼? 왜 컴파일러가 컴파일 할 수 없습니까? 왜 그 언어는 그렇게 작동합니까? – algal