Swift编译器错误:“表达式太复杂”在字符串连接上 [英] Swift Compiler Error: "Expression too complex" on a string concatenation

查看:124
本文介绍了Swift编译器错误:“表达式太复杂”在字符串连接上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得这很有趣,而不是任何事情。我已经修复了,但我想知道原因。这是错误: DataManager.swift:51:90:表达式太复杂,无法在合理的时间内解决;考虑将表达式分解成不同的子表达式。它为什么抱怨?它似乎是最简单的表达式之一。



编译器指向列+);; section

  func tableName() - > String {return(users); } 

func createTableStatement(schema:[String]) - >字符串{

var schema = schema;

schema.append(id string);
schema.append(created integer);
schema.append(updated integer);
schema.append(model blob);

var columns:String =,。join(schema);
$ b $ var statement =create table if not exists+ self.tableName()+(+ columns +);;

return(语句);
}

修正为:

  var statement =create table if not exists+ self.tableName(); 
statement + =(+ columns +);;

这也适用(通过@efischency),但我不喜欢它,因为我认为丢失:



var statement =create table if not exists \( self.tableName())(\(columns))

解决方案

编译器专家 - 我不知道这个答案是否会以一种有意义的方式改变你的想法,但我对这个问题的理解是这样的:

它有每次使用 + 运算符时,Swift都必须搜索 + ,并推断出你正在使用的是哪个版本的 + ,我对 + 操作符的重载计算了30个重载。很多可能性,并且当你将4或5 + 操作链接在一起并要求编译器推断出所有参数时,你所要求的要比它可能出现的要多得多乍一看。



推理可能会变得复杂 - 例如,如果使用 UInt8 Int > + ,输出将是 Int ,但是有一些工作可以用来评估混合类型和运算符的规则。



当你使用文字时,例如你的例子中的 String 文字,编译器将转换 String literal转换为 String ,然后完成推导 +如果一个表达式足够复杂 - 也就是说,它要求编译器对参数和运算符作出太多的推论,例如 - 退出并告诉你退出。



一旦表达式达到一定程度的复杂度,编译器就会退出。另一种方法是让编译器试着去做,然后看看它是否可以,但这是有风险的 - 编译器可能会继续尝试,停滞或只是崩溃。所以我的理解是,表达式的复杂性存在静态阈值,编译器不会超越。



我的理解是,Swift团队正在编译器优化会使这些错误不那么常见。 通过点击此链接,您可以在Apple Developer论坛上了解到这一点。



在开发论坛上,Chris Lattner已经要求人们将这些错误作为雷达报告提交,因为他们正在积极研究这些错误。



<这就是我在这里和Dev论坛上阅读大量文章后了解它的原因,但我对编译器的理解是天真的,我希望有更深入的知识来处理这些任务的人将会扩展我在这里写的。

I find this amusing more than anything. I've fixed it, but I'm wondering about the cause. Here is the error: DataManager.swift:51:90: Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions. Why is it complaining? It seems like one of the most simple expressions possible.

The compiler points to the columns + ");"; section

func tableName() -> String { return("users"); } 

func createTableStatement(schema: [String]) -> String {

    var schema = schema;

    schema.append("id string");
    schema.append("created integer");
    schema.append("updated integer");
    schema.append("model blob");

    var columns: String = ",".join(schema);

    var statement = "create table if not exists " + self.tableName() + "(" + columns + ");";

    return(statement);
}

the fix is:

var statement = "create table if not exists " + self.tableName();
statement += "(" + columns + ");";

this also works (via @efischency) but I don't like it as much because I think the ( get lost:

var statement = "create table if not exists \(self.tableName()) (\(columns))"

解决方案

I am not an expert on compilers - I don't know if this answer will "change how you think in a meaningful way," but my understanding of the problem is this:

It has to do with type inference. Each time you use the + operator, Swift has to search through all of the possible overloads for + and infer which version of + you are using. I counted just under 30 overloads for the + operator. That's a lot of possibilities, and when you chain 4 or 5 + operations together and ask the compiler to infer all of the arguments, you are asking a lot more than it might appear at first glance.

That inference can get complicated - for example, if you add a UInt8 and an Int using +, the output will be an Int, but there's some work that goes into evaluating the rules for mixing types with operators.

And when you are using literals, like the String literals in your example, the compiler doing the work of converting the String literal to a String, and then doing the work of infering the argument and return types for the + operator, etc.

If an expression is sufficiently complex - i.e., it requires the compiler to make too many inferences about the arguments and the operators - it quits and tells you that it quit.

Having the compiler quit once an expression reaches a certain level of complexity is intentional. The alternative is to let the compiler try and do it, and see if it can, but that is risky - the compiler could go on trying forever, bog down, or just crash. So my understanding is that there is a static threshold for the complexity of an expression that the compiler will not go beyond.

My understanding is that the Swift team is working on compiler optimizations that will make these errors less common. You can learn a little bit about it on the Apple Developer forums by clicking on this link.

On the Dev forums, Chris Lattner has asked people to file these errors as radar reports, because they are actively working on fixing them.

That is how I understand it after reading a number of posts here and on the Dev forum about it, but my understanding of compilers is naive, and I am hoping that someone with a deeper knowledge of how they handle these tasks will expand on what I have written here.

这篇关于Swift编译器错误:“表达式太复杂”在字符串连接上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆