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
Swift: nil requires a contextual type
提问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 value
parameter is described as:
其中value
参数描述为:
value
Initial value sent to observers when no other value has been received by the subject yet.
value
当主体尚未收到其他值时,将初始值发送给观察者。
And where Element
is 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 Element
as an Optional
type 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 .none
form for the nil
argument:
或者,让编译器MyData?
通过.none
对nil
参数使用非糖形式来推断占位符:
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 ReplaySubject
or PublishSubject
.
虽然@dfri 的回答在技术上是正确的,但在使用 RxSwift 时您可能需要考虑不同的类型。由于您希望主题仅在开始时为空,因此我建议使用ReplaySubject
or 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)