2016-10-21 6 views
1

컬렉션의 SubSequence를 String으로 변환하고 싶습니다. 예를 들어이 함수는 컬렉션의 처음 두 바이트를 수집하여이를 String으로 변환합니다.컬렉션의 하위 시퀀스를 문자열로 변환

func convert<T: Collection>(_ c: T) -> String 
    where T.Iterator.Element == UInt8 
{ 
    let start = c.startIndex 
    let end = c.index(after: start) 
    return String(bytes: c[start ... end], encoding: String.Encoding.utf8)! 
} 

이이 오류에 이르게 : 나는 여기에 무엇을 놓치고

error: ambiguous reference to member 'subscript' 
     return String(bytes: c[start ... end], encoding: String.Encoding.utf8)! 
          ~^~~~~~~~~~~~~~~ 
Swift.Collection:167:12: note: found this candidate 
    public subscript(position: Self.Index) -> Self.Iterator.Element { get } 
     ^
Swift.Collection:189:12: note: found this candidate 
    public subscript(bounds: Range<Self.Index>) -> Self.SubSequence { get } 
     ^
Swift.Collection:25:12: note: found this candidate 
    public subscript(bounds: Range<Self.Index>) -> Slice<Self> { get } 
     ^
Swift.IndexableBase:54:12: note: found this candidate 
    public subscript(position: Self.Index) -> Self._Element { get } 
     ^
Swift.IndexableBase:63:12: note: found this candidate 
    public subscript(bounds: Range<Self.Index>) -> Self.SubSequence { get } 
     ^
Swift.Indexable:23:12: note: found this candidate 
    public subscript(bounds: ClosedRange<Self.Index>) -> Self.SubSequence { get } 
     ^
Swift.Indexable:23:12: note: found this candidate 
    public subscript(bounds: CountableRange<Self.Index>) -> Self.SubSequence { get } 
     ^
Swift.Indexable:45:12: note: found this candidate 
    public subscript(bounds: CountableClosedRange<Self.Index>) -> Self.SubSequence { get } 

? :-)

+1

본문을'return String (bytes : c.prefix (2), encoding : .utf8)! '으로 단순화 할 수 있습니다! –

+0

확실합니다. 오류를 표시하는 단순화 된 예입니다. – Etan

답변

3

현재 CollectionSubSequenceassociatedtype의 제한으로 인해 컬렉션 자체와 동일한 요소 유형을 가질 수 있습니다.

사실, SE-0142: Permit where clauses to constrain associated types의 동기 중 하나는이 관계를 시행하는 associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == Iterator.Element 제한을 허용하는 것입니다.

당신이 첫번째 장소에있는 T.Iterator.Element == UInt8 제약 조건을 사용하지 않는으로이 특별한 경우에, 당신은 대신 T.SubSequence.Iterator.Element을 제한 할 수 있지만 (감사 @MartinR) :

func convert<T: Collection>(_ c: T) -> String 
    where T.SubSequence.Iterator.Element == UInt8 { 

    let start = c.startIndex 
    let end = c.index(after: start) 

    // please consider handling the case where String(bytes:encoding:) returns nil. 
    return String(bytes: c[start ... end], encoding: String.Encoding.utf8)! 
} 

(더 일반적인 경우에 경우 또한 주어진 유형에 제약이있는 T.Iterator.Element이 필요하면 T.SubSequence.Iterator.Element == T.Iterator.Element을 추가 제약 조건으로 추가해야합니다.

+1

같은 것을 게시하려고했습니다 :) - 단일 제약'T.SubSequence.Iterator.Element == UInt8'로 충분합니다. –

+0

@MartinR 아 그래, 네가 맞아 - 지적 해 주셔서 감사합니다 :) – Hamish

+0

두 제약이 실제로 필요한 단순화 된 예제였습니다. 두 경우에 대한 설명 주셔서 감사합니다! – Etan