无法将 'NodeType.NodeType?' 类型的 return 表达式转换为 return 类型 'NodeType?'
Cannot convert return expression of type 'NodeType.NodeType?' to return type 'NodeType?'
我已经在 Swift 中处理这个问题一段时间了,尝试了类型擦除和各种东西,但无济于事;这个问题似乎是常识(至少对我而言)。如何在 Swift 中模拟抽象 class?换句话说,如何进行这项工作:
import Foundation
protocol NodeProtocol
{
associatedtype NodeType
func getNode() -> NodeType
}
class Node: NodeProtocol
{
typealias NodeType = Node
var next:Node = Node()
func getNode() -> Node {
return next
}
}
class AbstractGraph<NodeType:NodeProtocol>
{
var root: NodeType?
func getRoot () -> NodeType?{
return root?.getNode()
}
}
注意:这只是我写的一些随机代码,只是为了触及问题的核心。
我不确定我是否正确理解了你的问题(你实际上问了一对夫妇)但这是我 'emulate' 在 [=42= 中抽象 classes 的方式] (4):
protocol Node {
func getNext() -> Node
}
extension Node {
func getNext() -> Node {
fatalError("getNext is not implemented!")
}
}
struct StringNode: Node {
var data: String!
}
let sNode = StringNode(data: "test-node-1")
sNode.getNext()
使用协议扩展,我决定需要使用 fatalError() 调用来实现哪些功能。
现在 Node
的每个节点后代都必须 实现 getNext() 否则我们会崩溃。 运行 上面的代码在操场上,你会看到它会在最后一行崩溃,迫使你实现 getNext()。
'fix' 将是:
protocol Node {
func getNext() -> Node
}
extension Node {
func getNext() -> Node {
fatalError("getNext is not implemented!")
}
}
struct StringNode: Node {
var data: String!
func getNext() -> Node {
return StringNode(data: "test-node-2")
}
}
let sNode = StringNode(data: "test-node-1")
sNode.getNext()
现在它不会在最后一行崩溃了。全部使用 Xcode 9 和 Swift 4.
在操场上测试
注意:这当然不是 Node
协议的最佳实现。该协议应列出可操作的方法,这些方法应表示 Node
称为 NodeOperatable
之类的东西。应创建名为 Node
的 class 来实现此 NodeOperatable
而不是实现 getNext()
,这将迫使后代 classes 实现 getNext()
。
试试这个:
class AbstractGraph<T: NodeProtocol> {
var root: T?
func getRoot () -> T.NodeType? {
return root?.getNode()
}
}
你怎么称呼类型并不重要。在上面我把它命名为T
。在您的系统中,您已将其命名为 NodeType
,如下所示:
class AbstractGraph<NodeType: NodeProtocol>
但是将 NodeType
重用为类型名称只是与 NodeProtocol
中的 associatedtype NodeType
名称有点混淆,人们希望两者相同,但实际上并非如此。
基本上你的 AbstractGraph
需要一个符合 NodeProtocol
.
的类型,比如 T
由于此类型 T
符合 NodeProtocol
,因此它自动包含 NodeType
属性。
此外,根据协议要求,getNode()
是 return this NodeType
属性.
因此在 getRoot()
中,因为你基本上 returning 什么 getNode()
是 returning,你需要 return 类型 T
的 NodeType
属性,而不是类型 T
本身。
我已经在 Swift 中处理这个问题一段时间了,尝试了类型擦除和各种东西,但无济于事;这个问题似乎是常识(至少对我而言)。如何在 Swift 中模拟抽象 class?换句话说,如何进行这项工作:
import Foundation
protocol NodeProtocol
{
associatedtype NodeType
func getNode() -> NodeType
}
class Node: NodeProtocol
{
typealias NodeType = Node
var next:Node = Node()
func getNode() -> Node {
return next
}
}
class AbstractGraph<NodeType:NodeProtocol>
{
var root: NodeType?
func getRoot () -> NodeType?{
return root?.getNode()
}
}
注意:这只是我写的一些随机代码,只是为了触及问题的核心。
我不确定我是否正确理解了你的问题(你实际上问了一对夫妇)但这是我 'emulate' 在 [=42= 中抽象 classes 的方式] (4):
protocol Node {
func getNext() -> Node
}
extension Node {
func getNext() -> Node {
fatalError("getNext is not implemented!")
}
}
struct StringNode: Node {
var data: String!
}
let sNode = StringNode(data: "test-node-1")
sNode.getNext()
使用协议扩展,我决定需要使用 fatalError() 调用来实现哪些功能。
现在 Node
的每个节点后代都必须 实现 getNext() 否则我们会崩溃。 运行 上面的代码在操场上,你会看到它会在最后一行崩溃,迫使你实现 getNext()。
'fix' 将是:
protocol Node {
func getNext() -> Node
}
extension Node {
func getNext() -> Node {
fatalError("getNext is not implemented!")
}
}
struct StringNode: Node {
var data: String!
func getNext() -> Node {
return StringNode(data: "test-node-2")
}
}
let sNode = StringNode(data: "test-node-1")
sNode.getNext()
现在它不会在最后一行崩溃了。全部使用 Xcode 9 和 Swift 4.
在操场上测试注意:这当然不是 Node
协议的最佳实现。该协议应列出可操作的方法,这些方法应表示 Node
称为 NodeOperatable
之类的东西。应创建名为 Node
的 class 来实现此 NodeOperatable
而不是实现 getNext()
,这将迫使后代 classes 实现 getNext()
。
试试这个:
class AbstractGraph<T: NodeProtocol> {
var root: T?
func getRoot () -> T.NodeType? {
return root?.getNode()
}
}
你怎么称呼类型并不重要。在上面我把它命名为T
。在您的系统中,您已将其命名为 NodeType
,如下所示:
class AbstractGraph<NodeType: NodeProtocol>
但是将 NodeType
重用为类型名称只是与 NodeProtocol
中的 associatedtype NodeType
名称有点混淆,人们希望两者相同,但实际上并非如此。
基本上你的 AbstractGraph
需要一个符合 NodeProtocol
.
的类型,比如 T
由于此类型 T
符合 NodeProtocol
,因此它自动包含 NodeType
属性。
此外,根据协议要求,getNode()
是 return this NodeType
属性.
因此在 getRoot()
中,因为你基本上 returning 什么 getNode()
是 returning,你需要 return 类型 T
的 NodeType
属性,而不是类型 T
本身。