Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 协议的所有实现的返回类型_Swift_Protocols - Fatal编程技术网

Swift 协议的所有实现的返回类型

Swift 协议的所有实现的返回类型,swift,protocols,Swift,Protocols,我有个小问题。我需要为一个函数指定一个返回值,该函数可以返回协议的每个实现。例如: 我的协议: protocol MyProtocol { //some functions } 实施: class ClassA: MyProtocol { } class ClassB: MyProtocol { } “问题”功能: func getClassByString(_ name: String) -> MyProtocol.Type { switch name {

我有个小问题。我需要为一个函数指定一个返回值,该函数可以返回协议的每个实现。例如:

我的协议:

protocol MyProtocol {
    //some functions
}
实施:

class ClassA: MyProtocol {
}

class ClassB: MyProtocol {
}
“问题”功能:

func getClassByString(_ name: String) -> MyProtocol.Type {
    switch name {
    case "a":
        return ClassA.self
    case "b":
        return ClassB.self
    default:
        return ClassC.self
    }
}
//编辑:这是我需要结果的地方

final class Mapper<N: MyProtocol> {
    public func map() -> N?{
        if let klass = N.self as? MyProtocol.Type {
            return klass as? N
        }
        return nil
    }
}
final类映射器{
公共函数映射()->N{
如果让klass=N.self as?MyProtocol.Type{
将klass返回为?N
}
归零
}
}
用法:

let className = "a" //this String comes from a JSON
let result = getClassByString(className)

let mappingResult = Mapper<result>().map() //undeclared identifier 'result' error
let mappingResult = Mapper<ClassA>().map() //works but i do not know if it is ClassA
let className=“a”//此字符串来自JSON
让结果=getClassByString(className)
让mappingResult=Mapper().map()//未声明的标识符'result'错误
让mappingResult=Mapper().map()//工作,但我不知道它是否是ClassA
问题是,
result
不是真正的
ClassA.Type
,它应该是什么,现在是
MyProtocol.Type
,我不能将它传递给下一个函数。 当我给出
result
ClassA.self的具体值时
一切正常。我无法将其转换为
as!ClassA.self
,因为我不知道它是否必须是
ClassA
ClassB
Class9000


所以问题是。函数
getClassByString()是否还有另一种返回类型,如
MyProtocol.type
或者一种完全不同的方式来获得
ClassA.Type
result

我认为你这里的问题与你描述的不完全一样-你的例子中的
result
看起来确实是一个
ClassA.Type
在操场上,但我怀疑的问题是你接下来该怎么处理它。您的协议没有说明如何以通用方式实例化此类类型,因此无法实例化返回的类型

我对您的示例做了一些更改,现在它可以工作了

protocol MyProtocol {
    //some functions
    init() // To instantiate generically, there MUST be an accepted pattern for init()
}

class ClassA: MyProtocol {
    required init() {}
}    
class ClassB: MyProtocol {
    required init() {}
}
class ClassC: MyProtocol {
    required init() {}
}

func getClassByString(_ name: String) -> MyProtocol.Type {
    switch name {
    case "a":
        return ClassA.self
    case "b":
        return ClassB.self
    default:
        return ClassC.self
    }
}

let className = "a" //this String comes from a JSON
let result = getClassByString(className) // ClassA.Type
let a = result.init() // ClassA

请注意,尽管
type(of:a)
将报告
ClassA
,但我们可能不会调用
ClassA
的实例方法,例如
a
上的
MyProtocol
中没有蓝图的
。假设
ClassA
有一个方法
foo()->()
,那么
a.foo()
将产生错误消息“error:type
MyProtocol
的值没有成员
foo
”。但我想这是意料之中的,否则Swift的静态类型在这种情况下会失败(编译时未确定)。@dfri-这正是我的观点-调用
init()
it A)必须在协议中指定,B)必须在实现中
必需
,事实上,我已经明确指出了这一点(主要针对OP)我相信OP正在试图解决XY问题,使用的方法不适合Swift这样的静态类型语言。最后,OP将只能使用
MyProtocol
分层类型,因为我们在编译时永远无法知道
a
的具体类型,这导致OP对
(a as!ClassA).foo()进行推理。我推测,朝这个方向进行将导致OP的代码推理,并且他/她可能希望在继续尝试“运行时键入”之前重新访问原始问题(…可能值得一提的是,即使我们“一般地”实例化
a
)(由蓝图提供的
init
)上面,这还没有结束:
a
仍然不是一个具体的
ClassA
,如果不熟悉Swift的静态类型本质,这可能会从上面答案中的最后一段代码中被误解。谢谢你的回答。我编辑了我的问题,以便更清楚地说明我需要什么
result