我正在尝试在XCode 11中尝试使用功能构建器,并构建了这个简单的游乐场。似乎没有使用函数生成器将输入转换为所需的结果闭包,但是我觉得我必须在某处缺少要点。最后一行报告的错误为cannot convert value of type '(Int, Int)' to closure result type 'Scene'
import SpriteKit
public protocol Scene {
var width : Int {get}
var height : Int {get}
}
public struct EmptyScene : Scene {
public let width : Int
public let height: Int
}
@_functionBuilder public struct SceneBuilder {
public static func buildBlock(_ size:(Int,Int))->Scene {
return EmptyScene(width: size.0, height: size.1)
}
}
extension SKScene {
public convenience init(@SceneBuilder _ scene : () -> Scene){
let definition = scene()
self.init(size: CGSize(width: definition.width, height: definition.height))
}
}
SKScene {
(320,256)
}
答案 0 :(得分:1)
我认为您错过了一步。我认为函数构建器是我必须添加到函数中的注释,因此带注释的函数具有更好的调用位置(仅在大括号内包含一些值,可以帮助快速进行合成/填充)。我对SpriteKit不太了解,但编译器对此感到满意:
import PlaygroundSupport
import SpriteKit
import SpriteKit
public protocol Scene {
var width : Int {get}
var height : Int {get}
}
public struct EmptyScene : Scene {
public let width : Int
public let height: Int
}
@_functionBuilder public struct SceneBuilder {
public static func buildBlock(_ size:(Int,Int))->Scene {
return EmptyScene(width: size.0, height: size.1)
}
}
extension SKScene {
public convenience init(@SceneBuilder _ scene : () -> Scene){
let definition = scene()
self.init(size: CGSize(width: definition.width, height: definition.height))
}
}
*here*
@SceneBuilder
func buildDaScene() -> Scene { (320, 256) }
SKScene { buildDaScene() }
答案 1 :(得分:0)
这是一个Swift错误:函数构建器中不考虑单表达式闭包。 (请参阅here,尽管目前尚不清楚哪个Swift版本可以解决该问题。)
我添加了另一个buildBlock
方法,该方法采用多个元组(并且忽略除第一个之外的所有元组),并且确实可以使用。
@_functionBuilder public struct SceneBuilder {
// no difference whether or not we keep the old buildBlock as well
public static func buildBlock(_ size: (Int,Int)...) -> Scene {
return EmptyScene(width: size[0].0, height: size[0].1)
}
}
SKScene {
(320,256)
} // won't compile
SKScene {
(320,256)
(321,257)
} // creates one SKScene with (320,256)
无论如何,将单表达式闭包传递给函数恰好是您不需要需要函数生成器的用例,并且按预期工作:
extension SKScene {
public convenience init(_ tupleClosure: () -> (Int,Int)){
self.init(size: CGSize(width: tupleClosure().0, height: tupleClosure().1))
}
}
SKScene {
(320, 256)
} // creates the scene
如果要在闭包中处理所有后续表达式,则需要函数构建器,而在引入此功能之前是不可能的。
所以好消息是您已经知道如何构造它们(嗯,在11月就已经知道了:)),并且它们应该与多个表达式一起使用……并且单个表达式的解决方案已经存在(还有一种解决方法那些。)