xcode Swift:nil 需要上下文类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51465089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 10:42:50  来源:igfitidea点击:

Swift: nil requires a contextual type

iosswiftxcoderx-swift

提问by breakline

I'd like to achieve the following in code:

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

class MyService {

    let mySubject = BehaviorSubject<MyData>(value: nil)

    //....

}

Unfortunately I get the "nil requires a contextual type" error. I want the subject to be "empty" till I actually put something in there. How can I pass nil as the argument then? Can I cast it to my own type to make it work?

不幸的是,我收到“nil 需要上下文类型”错误。我希望主题是“空的”,直到我真正在那里放了一些东西。那么我如何将 nil 作为参数传递呢?我可以将它转换为我自己的类型以使其工作吗?

回答by dfri

Based on the reference for RxSwift BehaviorSubject, the init(value:)initializer is declared as

基于RxSwiftBehaviorSubject参考init(value:)初始化器声明为

public init(value: Element)
public init(value: Element)

Where the valueparameter is described as:

其中value参数描述为:

value

Initial value sent to observers when no other value has been received by the subject yet.

value

当主体尚未收到其他值时,将初始值发送给观察者。

And where Elementis the placeholder type of BehaviorSubject:

Element的占位符类型在哪里BehaviorSubject

public final class BehaviorSubject<Element> ...
public final class BehaviorSubject<Element> ...

This means you need to specify the placeholder type Elementas an Optionaltype if you are to be able to set the initial value (used when no other value has been received) to nil. E.g.:

你需要指定占位类型,这意味着Element作为一个Optional类型,如果你能够到初始值(当没有接收到其他值使用)设置nil。例如:

class MyService {

    let mySubject = BehaviorSubject<MyData?>(value: nil)

    //....
}

Or, letting the compiler infer the placeholder as MyData?by using the non-sugared .noneform for the nilargument:

或者,让编译器MyData?通过.nonenil参数使用非糖形式来推断占位符:

class MyService {

    let mySubject = BehaviorSubject(value: Optional<MyData>.none)

    //....
}


As for understanding the actual error message better, consider the following self-contained example:

至于更好地理解实际错误消息,请考虑以下独立示例:

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?

回答by Yannick

While @dfri's answer is technically correct, you might want to consider a different type when working with RxSwift. Since you want your subject to be empty only at the beginning, I'd suggest to use ReplaySubjector PublishSubject.

虽然@dfri 的回答在技术上是正确的,但在使用 RxSwift 时您可能需要考虑不同的类型。由于您希望主题仅在开始时为空,因此我建议使用ReplaySubjector PublishSubject

A similar question has also been asked on RxSwift's Github issue page. Allow BehaviorSubject without initial value. There, kzaher suggests the ReplaySubject.

在 RxSwift 的 Github 问题页面上也提出了类似的问题。允许 BehaviorSubject 没有初始值。在那里,kzaher 建议使用ReplaySubject.

Your subject would then look like this, without any initial value and without MyData being Optional.

您的主题将看起来像这样,没有任何初始值,也没有 MyData Optional

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