【问题标题】:Why can't I use a Metatype as a property on a struct in swift?为什么我不能在 swift 中使用元类型作为结构的属性?
【发布时间】:2018-07-10 00:09:21
【问题描述】:

所以我想知道当我尝试使用 Metatype 作为属性类型来实例化一个结构时,我的 Playground 崩溃了,但当我对类执行相同操作时却没有。

结构版本:

struct Dog {
    static func saySomething() {
        print("Woof")
    }
}

我创建了一个带有元类型绑定属性的结构PetOwner,并对其进行了编译。

struct PetOwner {
    let name: String
    let pet: Dog.Type
}

当我尝试使用它时,游乐场崩溃了。

// Crashes
let dogOwner = PetOwner(
    name: "Joe",
    pet: Dog.self
)

但是,当我将PetOwner 设为一个类时:

class PetOwner {
    let name: String
    let pet: Speaking.Type

    init(name: String, pet: Dog.Type) {
        self.name = name
        self.pet = pet
    }
}

然后我可以实例化那个类并调用静态方法:

let dogOwner = PetOwner(
    name: "Joe",
    pet: Dog.self
)

dogOwner.pet.saySomething() // Woof

为什么会这样?尝试实例化结构版本的错误消息非常难以理解:

错误:执行被中断,原因:EXC_BAD_ACCESS (代码=EXC_I386_GPFLT)。该过程已留在它所在的位置 被中断,使用“thread return -x”返回之前的状态 表达式求值。

但真正奇怪的部分是,如果我绑定了 Metatype 协议,那么它会再次与结构一起工作:

protocol Speaking {
    static func saySomething()
}

struct Dog: Speaking {
    static func saySomething() {
        print("Woof")
    }
}

struct PetOwner {
    let name: String
    let pet: Speaking.Type
}

// Works!
let dogOwner = PetOwner(
    name: "Joe",
    pet: Dog.self
)
dogOwner.pet.saySomething() // Woof

我在这里错过了什么?

【问题讨论】:

  • 它对我有用,尽量不要使用 Playground,而是使用 .swift 文件

标签: swift class struct protocols metatype


【解决方案1】:

这是你要找的吗?

//: Playground - noun: a place where people can play

import UIKit

struct Dog {
    static func saySomething() {
        print("Woof")
    }
}

struct PetOwner {
    let name: String
    let pet: Dog
}

let dog = Dog()

// Won't crash
let dogOwner = PetOwner(
    name: "Joe",
    pet: dog
)

dogOwner.pet

看起来您正在尝试访问 Dog.Type(您正在调用 Dog.self,而 Dog 实际上是 Dog.type...所以您在做 Dog.type.self...我想?)。请注意,在结构中必须创建一个狗对象,在类中,您不需要。

【讨论】:

  • 如果您尝试致电dogOwner.pet.saySomething(),您就会明白我为什么不赞成这个答案。这个想法是你传递一个可以调用静态方法的元类型。您的回答显示了如何传递您无法调用静态方法的实例类型。
猜你喜欢
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 2014-01-15
  • 2011-07-20
  • 1970-01-01
  • 2015-08-14
  • 1970-01-01
相关资源
最近更新 更多