简体   繁体   English

如何在Swift中声明返回自定义结构序列的方法

[英]How do declare methods that return a Sequence of custom Structs in Swift

What is the proper way to declare a function that return a Sequence in Swift 4. I tried the following but receive a error stating: 声明在Swift 4中返回Sequence的函数的正确方法是什么?我尝试了以下操作,但收到一条错误消息:

error: Models.playground:29:13: error: cannot convert return expression of type 'Cars' to return type 'S' return Cars(cars) ^~~~~~~~~~ as! 错误:Models.playground:29:13:错误:无法将类型'Cars'的返回表达式转换为类型'S'return Cars(cars)^ ~~~~~~~~~ as! S 小号

Here is the code I used: 这是我使用的代码:

import Foundation

struct Car {
    let make:String
    let model:String
}

class Cars: Sequence, IteratorProtocol {
    typealias Element = Car

    var current = 0
    let cars:[Element]
    init(_ cars:[Element]) {
        self.cars = cars;
    }

    func makeIterator() -> Iterator {
        current = 0
        return self
    }

    func next() -> Element? {
        if current < cars.count {
            defer { current += 1 }
            return cars[current]
        } else {
            return nil
        }
    }
}

let cars = Cars([Car(make:"Buick", model:"Century"), Car(make:"Buick", model:"LaSabre")])

func getCars<S:Sequence>(cars:[Car]) -> S where S.Iterator.Element == Car {
    return  Cars(cars)
}

The return value cannot be a specialization of the Sequence protocol. 返回值不能是Sequence协议的特殊化。 You can either return Cars itself, as Daniel suggested , or – if you want to hide the implementation of the sequence – a “type-erased” sequence: 您可以按照Daniel的建议 ,返回Cars本身,或者-如果您想隐藏序列的实现,则可以使用“类型擦除”序列:

func getCars(cars:[Car]) -> AnySequence<Car> {
    return AnySequence(Cars(cars))
}

or even 甚至

func getCars(cars:[Car]) -> AnySequence<Car> {
    return AnySequence(cars)
}

AnySequence is a generic struct conforming to the Sequence protocol which forwards to the underlying sequence or iterator from which it was created. AnySequence是符合Sequence协议的通用结构,该协议转发到从其创建基础序列或迭代器。 See also A Little Respect for AnySequence for more examples. 有关更多示例,另请参见对AnySequence的一点尊重

Remark: Similarly, it is possible to make Cars a Sequence by returning a type-erased iterator which forwards to the array iterator: 备注:类似地,可以通过返回转发到数组迭代器的类型擦除的迭代器来使Cars成为Sequence

class Cars: Sequence {
    typealias Element = Car

    let cars: [Element]
    init(_ cars: [Element]) {
        self.cars = cars;
    }

    func makeIterator() -> AnyIterator<Element> {
        return AnyIterator(cars.makeIterator())
    }
}

The problem is that you are using a generic for a specific type. 问题是您对特定类型使用泛型。 You can either return a Cars element (note that Cars conforms to Sequence , so you are returning a Sequence here): 您可以返回Cars元素(请注意Cars符合Sequence ,因此您将在此处返回Sequence ):

func getCars(cars: [Car]) -> Cars {
    return  Cars(cars)
}

or use a generic (also a Sequence , since it is defined in the generic): 或使用通用名称(也可以使用Sequence ,因为它是在通用名称中定义的):

func getCars<S: Sequence>(cars: [Car]) -> S {
    return cars as! S
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM