swift - 在函数中接收正确的类型

标签 swift macos cocoa

我尝试构建一些 NestedView,它在 View 内部加载 View ...取决于对象树。所以我在 Playground 中做了一个简短的测试:

class First {}
class Second:First {}

class Dodd {
    func takeIt<Foo, Bar>(content:[Foo], type: Bar.Type) {
        print (Foo.self, Bar.self)
     print (content as? [Bar] ?? [])
    }
}

let arrayOfFirst:[First] = [First()]
let arrayOfSecond:[Second] = [Second(), Second(), Second()]

let dodd = Dodd()

let firstType = First.self
let secondType = Second.self

dodd.takeIt(content: arrayOfSecond, type: firstType)
dodd.takeIt(content: arrayOfFirst, type: secondType)

它产生良好且可预测的输出:

Second First
[__lldb_expr_77.Second, __lldb_expr_77.Second, __lldb_expr_77.Second]
First Second
[]
太棒了。 但如果我尝试在更复杂的环境中使用完全相同的机制,结果就不太令人满意。 这是某些 ViewController 的功能,无论如何:

func addSubviews<HeadType>(for content:[HeadType]) {

        Swift.print("ADD SUBVIEW FOR \(HeadType.self)")

        func takeNext <ParentType, ChildType>(
            parentArray: [ParentType],
            pathToChild: AnyKeyPath,
            type: ChildType.Type?) -> [ChildType]

        {
            Swift.print ("\nInside takeNext Child Type <\(ChildType.self)>\n")
            let result:[ChildType] = parentArray.flatMap { ( parentElement ) -> ChildType? in
                parentElement [keyPath:pathToChild] as? ChildType}
            return result
        }

        let interfaceHead = InterfaceElements(type: HeadType.self)
        Swift.print ("\tParentArrayContent: \(HeadType.self) ")
        for (label, path) in interfaceHead.paths {

            if let firstObject = content.first, let objectAtKeyPath = firstObject[ keyPath:path ] {
                Swift.print ("\t\tpath: \(path)")
                Swift.print ("\t\ttype: \(InterfaceElements(element: objectAtKeyPath).type.self)")
                Swift.print("\t\tLabel", label)
                let childType = InterfaceElements(element: objectAtKeyPath).type
                let elements = takeNext(
                    parentArray: content,
                    pathToChild: path,
                    type: childType)

                let controller = NestedStackViewController(for: elements)

            }
        }
    }

输出:

ADD SUBVIEW FOR Joint
    ParentArrayContent: Joint 
        path: Swift.ReferenceWritableKeyPath<HyperGlyph.Joint, Swift.ImplicitlyUnwrappedOptional<HyperGlyph.Position>>
        type: Optional(HyperGlyph.Position)
        Label position

Inside takeNext Child Type <NSManagedObject>

ADD SUBVIEW FOR NSManagedObject
    ParentArrayContent: NSManagedObject 
inited NestedStack for  NSManagedObject
inited NestedStack for  Joint

第一个循环很好,Joint是Joint,找到Position类型,发送到takeNext,但是在takeNext函数中Position变成了NSManagedObject类型。哪里可能有诡计?

最佳答案

只有一种方法是显式传递类型。

let elements = takeNext(
                parentArray: content,
                pathToChild: path,
                type: SomeType.self) // << Here.

它使程序变得更加复杂,更多的开关,但现在它以良好的强类型方式工作。

关于swift - 在函数中接收正确的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48526657/

相关文章:

ios - 检查 UIImage 是否是横向图像

ios - 如何在 NSDate 中附加 UTC

ios - SpriteKit iPad View 缩放

macos - 如何让终端程序支持光标键?

objective-c - OSX 用字典填充弹出按钮

ios - 为一副纸牌中的每个 Card 实例赋值

macos - 如何在Mac OS上安装较新版本的make?

ios - "iPhone Distribution"证书不受信任

javascript - 有什么方法可以停止或暂停 JSContext 对象中 Javascript 的执行?

objective-c - 动态更改 Popover View 框架