swift – 传递给#keyPath()的非字符串“属性名称”可以独立保存吗?

swift – 传递给#keyPath()的非字符串“属性名称”可以独立保存吗?,第1张

概述我很高兴找到 Swift 3的#keyPath()实现,这将消除拼写错误并在编译时强制执行密钥路径.比手动键入字符串要好得多. https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md class MyObject { @objc var myString: String = " 我很高兴找到 Swift 3的#keyPath()实现,这将消除拼写错误并在编译时强制执行密钥路径.比手动键入字符串要好得多.

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md

class MyObject {    @objc var myString: String = "default"}// Works greatlet keypathstring = #keyPath(MyObject.myString)

Swift docs list the type作为“属性名称”传递给#keyPath().

The property name must be a reference to a property that is available in the Objective-C runtime. At compile time,the key-path Expression is replaced by a string literal.

可以独立保存这个“属性名称”,然后传递给#keyPath()来创建一个String吗?

let propertyname = MyObject.myString // error. How do I save?let string = #keyPath(propertyname)

是否支持要求属于特定类型的属性名称?

// something like thislet typedPropertyname: MyObject.Propertyname = myString // errorlet string = #keyPath(typedPropertyname)

最终目标将与需要NSExpression作为密钥路径的API进行交互.我想编写方便的方法,将有效的属性名称作为参数,而不是随机密钥路径字符串.理想情况下,由特定类型实现的属性名称.

func doSomethingForSpecificTypeProperty(_ propertyname: MyObject.Propertyname) {    let keypathstring = #keyPath(propertyname)    let Expression = NSExpression(forKeyPath: keypathstring)    // ...}
它看起来不可能.

这是解析密钥路径表达式的编译器代码:

///   expr-keypath:///     '#keyPath' '(' @R_301_1464@ ('.' @R_301_1464@) * ')'///ParserResult<Expr> Parser::parseExprKeyPath() {  // Consume '#keyPath'.  SourceLoc keywordLoc = consumetoken(tok::pound_keyPath);  // Parse the leading '('.  if (!Tok.is(tok::l_paren)) {    diagnose(Tok,diag::expr_keypath_expected_lparen);    return makeParserError();  }  SourceLoc lParenLoc = consumetoken(tok::l_paren);  // Handle code completion.  SmallVector<IDentifIEr,4> names;  SmallVector<SourceLoc,4> nameLocs;  auto handleCodeCompletion = [&](bool hasDot) -> ParserResult<Expr> {    ObjCKeyPathExpr *expr = nullptr;    if (!names.empty()) {      expr = ObjCKeyPathExpr::create(Context,keywordLoc,lParenLoc,names,nameLocs,Tok.getLoc());    }    if (CodeCompletion)      CodeCompletion->completeExprKeyPath(expr,hasDot);    // Eat the code completion token because we handled it.    consumetoken(tok::code_complete);    return makeParserCodeCompletionResult(expr);  };  // Parse the sequence of @R_301_1464@s.  ParserStatus status;  while (true) {    // Handle code completion.    if (Tok.is(tok::code_complete))      return handleCodeCompletion(!names.empty());    // Parse the next name.    DeclnameLoc nameLoc;    bool afterDot = !names.empty();    auto name = parseUnqualifIEdDeclname(                  afterDot,nameLoc,diag::expr_keypath_expected_property_or_type);    if (!name) {      status.setIsParseError();      break;    }    // Cannot use compound names here.    if (name.isCompoundname()) {      diagnose(nameLoc.getBasenameLoc(),diag::expr_keypath_compound_name,name)        .fixItReplace(nameLoc.getSourceRange(),name.getBasename().str());    }    // Record the name we parsed.    names.push_back(name.getBasename());    nameLocs.push_back(nameLoc.getBasenameLoc());    // Handle code completion.    if (Tok.is(tok::code_complete))      return handleCodeCompletion(false);    // Parse the next period to continue the path.    if (consumeIf(tok::period))      continue;    break;  }  // Parse the closing ')'.  SourceLoc rParenLoc;  if (status.isError()) {    skipUntilDeclStmtRBrace(tok::r_paren);    if (Tok.is(tok::r_paren))      rParenLoc = consumetoken();    else      rParenLoc = PrevIoUsLoc;  } else {    parseMatchingToken(tok::r_paren,rParenLoc,diag::expr_keypath_expected_rparen,lParenLoc);  }  // If we cannot build a useful Expression,just return an error  // Expression.  if (names.empty() || status.isError()) {    return makeParserResult<Expr>(             new (Context) ErrorExpr(SourceRange(keywordLoc,rParenLoc)));  }  // We're done: create the key-path Expression.  return makeParserResult<Expr>(           ObjCKeyPathExpr::create(Context,rParenLoc));}

此代码首先在括号内创建一个以句点分隔的名称列表,然后尝试将它们解析为表达式.它接受表达式而不是任何Swift类型的数据;它接受代码,而不是数据.

总结

以上是内存溢出为你收集整理的swift – 传递给#keyPath()的非字符串“属性名称”可以独立保存吗?全部内容,希望文章能够帮你解决swift – 传递给#keyPath()的非字符串“属性名称”可以独立保存吗?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1029890.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存