我有以下枚举:
@dynamicMemberLookup
enum JSCall: ExpressibleByStringInterpolation {
case getElement(String)
case getInnerHTML(id: String)
case removeAttribute(id: String, attributeName: String)
case customScript(String)
case document
indirect case chainedCall(JSCall, String)
var value: String {
switch self {
case .document:
return "document"
case .getElement(let id):
return JSCall.chainedCall(.document, "getElementById('\(id)')").value
case .getInnerHTML(let id):
return JSCall.getElement(id).innerHTML.value // Using dynamic member lookup here
case .removeAttribute(let id, let attribute):
return JSCall.chainedCall(.getElement(id), "removeAttribute('\(attribute)')").value
case .chainedCall(let prefixJs, let suffix):
return "\(prefixJs.scriptString)\(STRING_DOT)\(suffix)"
case .customScript(let script):
return script
}
}
init(stringLiteral value: String) {
self = .customScript(value)
}
subscript(dynamicMember suffix: String) -> JSCall {
return .chainedCall(.customScript(self.value), suffix)
}
}
注意,在计算(computed)属性value
中,对于getInnerHTML
种情况,我可以使用自然语法通过点语法链接.innerHTML,这要归功于@dynamicMemberLookup
.但是,如果我try 链接插入的字符串,如下所示:
let call = JSCall.document.getElementById('\(id)').value
我收到了类似Cannot call value of non-function type 'JSCall'的编译器错误.
我以为符合ExpressibleByStringInterpolation
标准就能解决问题,但事实并非如此.
有没有办法在这个枚举中实现链接方法调用的自然语法?