代码之家  ›  专栏  ›  技术社区  ›  breakline

swift:nil需要上下文类型

  •  3
  • breakline  · 技术社区  · 6 年前

    我想在代码中实现以下目标:

    class MyService {
    
        let mySubject = BehaviorSubject<MyData>(value: nil)
    
        //....
    
    }
    

    不幸的是,我得到“nil需要上下文类型”错误。我希望这个主题是“空的”,直到我把东西放进去。那我怎么能把零当作论点传下去呢?我能把它铸造成我自己的类型使它工作吗?

    2 回复  |  直到 6 年前
        1
  •  9
  •   dfrib    6 年前

    基于 reference for RxSwift BehaviorSubject , the init(value:) 初始值设定项声明为

    public init(value: Element)
    

    在哪里 value 参数描述如下:

    价值

    未收到其他值时发送给观察者的初始值 到现在为止。

    在哪里? Element 是占位符类型 行为主体 :

    public final class BehaviorSubject<Element> ...
    

    这意味着您需要指定占位符类型 元素 作为一个 Optional 如果要将初始值(在没有收到其他值时使用)设置为 nil . 例如。:

    class MyService {
    
        let mySubject = BehaviorSubject<MyData?>(value: nil)
    
        //....
    }
    

    或者,让编译器将占位符推断为 MyData? 用无糖的 .none 参数:

    class MyService {
    
        let mySubject = BehaviorSubject(value: Optional<MyData>.none)
    
        //....
    }
    

    为了更好地理解实际的错误消息,请考虑以下自包含的示例:

    struct Foo<T> {
        init(value: T) {}
    }
    
    struct Bar {}
    
    let bar = Bar()
    
    _ = Foo<Bar>(value: bar)           // OK
    _ = Foo(value: bar)                // OK, T inferred as Bar
    _ = Foo<Bar>(value: nil)           // Error: error: 'nil' requires a contextual type
    _ = Foo<Bar?>(value: nil)          // OK
    _ = Foo(value: Optional<Bar>.none) // OK, T inferred as Bar?
    
        2
  •  1
  •   Yannick    6 年前

    虽然@dfri的答案在技术上是正确的,但是在使用Rxswift时,您可能需要考虑不同的类型。既然你希望你的主题一开始是空的,我建议你用 ReplaySubject PublishSubject .

    Rxswift的Github问题页面也提出了类似的问题。 Allow BehaviorSubject without initial value . 在那里,Kzaher建议 可替换主题 .

    然后,您的主题将是这样的,没有任何初始值,也没有mydata Optional .

    let subject = ReplaySubject<MyData>().create(bufferSize: 1)