无法转换“Foo!”类型的值到预期的参数类型'Foo!'

Posted

技术标签:

【中文标题】无法转换“Foo!”类型的值到预期的参数类型\'Foo!\'【英文标题】:Cannot convert value of type 'Foo!' to expected argument type 'Foo!'无法转换“Foo!”类型的值到预期的参数类型'Foo!' 【发布时间】:2017-09-12 03:11:46 【问题描述】:

我遇到过几次事情让我感到困惑。我有时会收到类似于以下的错误

无法转换 'Foo!' 类型的值到预期的参数类型 'Foo!

'

我已经搜索过 SO,但还没有真正找到任何解释为什么 Foo!和 Foo! 不一样。

这是一个例子:

// FooViewModel.swift
class FooViewModel: BaseViewModel 
    fileprivate var foo: Foo!
    fileprivate var bar: Bar = Bar()

    init!(model: Foo!) 
        super.init()
        foo = model
    

    override init() 
        super.init()
    

    func setFooModel(_ model: Foo!) 
        self.foo = model
    

    func getFooModel() -> Foo! 
        return self.foo
    

    func getBar() -> Bar 
        return bar
    

    func getBlah() -> String 
        return "Blah"
    

这是产生错误的单元测试:

import XCTest
@testable import WooHoo

class FooViewModelTests: XCTestCase 

    override func setUp() 
        super.setUp()
    

    override func tearDown() 
        super.tearDown()
    

    func testGetBar() 
        var foo = Foo()
        let vm = FooViewModel()

        // The following line generates the error
        vm.setFooModel(foo)

        XCTAssertEqual("Tell us your Foo for the Bar program.", vm.getBlah())
    

我尝试了vm.setFooModel(foo) 的多种变体,但均无济于事,例如vm.setFooModel(foo!) 或将 foo 声明为 var foo: Foo! = Foo()

编辑: 请注意,上面的代码用于说明我遇到的问题,而不是操作代码。

【问题讨论】:

Foo 类型声明在哪里?是否有可能在不同的范围内声明了多个Foo 我认为你只需要在声明变量foo时使用Foo!,在其他地方只需使用Foo setFooModelgetFooModel 方法的意义何在?为什么不直接公开foo 属性? getBar 方法相同。为什么不简单地将bar 属性设置为具有公共读取访问权限? 将属性声明为在 init 方法中初始化的隐式未包装可选项是荒谬的。不要那样做。如果您想要一个可选的,请使用常规可选?,否则使用非可选类型。 为什么在initFoo 参数类型之后使用!?初始化器要么是失败的,要么不是。你不能有一个强制解包的可选返回类型,但你可以有一个非可选的返回类型,你可以在 return 语句中强制解包。参数也是如此,如果您希望参数作为非可选参数,则将该参数声明为非可选参数并在调用点展开。 【参考方案1】:

我想通了。我的视图模型是测试目标的一部分。在我将其设置为仅运行目标后,问题就解决了。仅供参考。

【讨论】:

以上是关于无法转换“Foo!”类型的值到预期的参数类型'Foo!'的主要内容,如果未能解决你的问题,请参考以下文章

无法转换“CGPoint!”类型的值到预期的参数类型'UnsafeMutablePointer<CGPoint>'

无法转换类型“[String : AnyObject]?”的值到预期的参数类型“[NSAttributedStringKey:Any]?”

无法转换类型“Meme!”的值到预期的参数类型'@noescape (Meme) throws -> Bool'

无法转换类型“Range<Int>?”的值到预期的参数类型'Range<String.Index>?

无法转换类型“[String]?”的值到预期的参数类型“字符串?”快速显示结构中的图像时

无法将“字符串”类型的值转换为预期的参数类型 [任何]