programing

Swift 컴파일러 오류: 문자열 연결 시 "표현이 너무 복잡함"

megabox 2023. 4. 14. 21:33
반응형

Swift 컴파일러 오류: 문자열 연결 시 "표현이 너무 복잡함"

나는 무엇보다도 이것이 재미있다고 생각한다.이치노.DataManager.swift:51:90: Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions★★★★★★★★★★★★★★★★★?가능한 가장 간단한 표현 중 하나인 것 같습니다.

는 「」를 .columns + ");"; 표시

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);
}

수정사항은 다음과 같습니다.

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

도 (@통해서)가 있는데, 는 @efischency가 요.( 로스트:

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

저는 컴파일러 전문가가 아닙니다.이 답변이 "의미 있는 방식으로 사고방식을 바꿀 수 있을지는 모르겠지만, 이 문제에 대한 저의 이해는 다음과 같습니다.

이치노+. Swift는 오버로드가 발생할 수 있습니다.+.+사용하고 있습니다.는 30분의 를 30분의 1 .+, 5번, , 5번, 4번, 5번, 4번, 5번, 4번, 5번, 4번, 5번, 4번, 5번, 4번, 4번, 5번, 4번, 4번, 4번, 5번, 4번, 4번, 4번, 5번 4번, 4번, 4번, 4번, 4번, 5번, 4번, 5+컴파일러에게 모든 인수를 추론하도록 요구하면 언뜻 보기보다 훨씬 더 많은 것을 요구할 수 있습니다.

추론은 수 . 를 들어 '그러다'를요. 예예 、 를를 、 ,를 、UInt8 ★★★Int를 사용합니다.+은 「」이 됩니다Int그러나 연산자와 활자를 혼합하는 규칙을 평가하는 작업이 있습니다.

는 리터럴을 합니다.String.String 그대로String+오퍼레이터 등

식이 충분히 복잡한 경우(즉, 컴파일러가 인수와 연산자에 대해 너무 많은 추론을 해야 함)는 종료하고 종료되었음을 알려줍니다.

식이 어느 정도 복잡해지면 컴파일러를 종료시키는 것은 의도적인 것입니다.다른 방법은 컴파일러가 시도하고 실행할 수 있는지 확인하는 것입니다.그러나 그것은 위험합니다.컴파일러는 계속 시도하거나 정지하거나 크래시 할 수 있습니다.따라서 컴파일러가 넘지 않는 식의 복잡성에는 정적 임계값이 존재한다고 생각합니다.

제가 알기로는 Swift 팀은 이러한 오류를 덜 흔하게 만드는 컴파일러 최적화 작업을 하고 있습니다.Apple Developer 포럼에서 이 링크를 클릭하면 자세한 내용을 볼 수 있습니다.

개발 포럼에서 Chris Ratner는 사람들에게 이러한 오류를 레이더 보고서로 제출하도록 요청했습니다. 왜냐하면 그들은 적극적으로 오류를 수정하는 작업을 하고 있기 때문입니다.

여기와 Dev 포럼에서 많은 글을 읽고 그렇게 이해하게 되었습니다만, 컴파일러에 대한 저의 이해는 순진하기 때문에, 이러한 작업에 대해 보다 깊이 있는 지식을 가지고 있는 사람이, 여기에 써 온 내용을 확대해 주었으면 합니다.

이는 수용된 답변과 거의 동일하지만 몇 가지 대화(Rob Napier, 그의 다른 답변 및 Matt, Oliver, David from Slack) 및 링크가 추가되었습니다.

설명의 코멘트를 참조해 주세요.요점은 다음과 같습니다.

+과부하가 심합니다(애플이 경우에 따라 이 문제를 수정한 것 같습니다).

연산자는 과부하가 심합니다.현재 27개의 다른 함수를 가지고 있습니다.따라서 4개의 문자열을 연결할 경우 3개의 문자열이 있습니다.+연산자는 매번 27개의 연산자를 체크해야 하므로 27^3배입니다.그러나 그게 아닙니다.

또한 체크가 있습니다.lhs ★★★★★★★★★★★★★★★★★」rhs+가 모두 합니다.이이 되는 경우입니다.append불렀다.여기에서는 다소 집중적인 체크가 여러 개 발생할 수 있음을 알 수 많은 것을 알 수 있습니다.문자열이 비연속적으로 저장되어 있는 경우, 이것은 취급하는 문자열이 실제로 NSString에 브리지되어 있는 경우에 해당합니다.그런 다음 Swift는 모든 바이트 배열 버퍼를 하나의 연속 버퍼로 재구성해야 합니다.그러면 중간에 새로운 버퍼를 생성해야 합니다.그러면 최종적으로 연결하려는 문자열을 포함하는 버퍼가1개 생깁니다.

즉, 컴파일러 체크 클러스터가 3개 있기 때문에 속도가 느려집니다.즉, 각 서브 표현식반환될 수 있는 모든 것을 고려하여 재검토해야 합니다.그 결과 문자열과 보간(예:" My fullName is \(firstName) \(LastName)" "My firstName is" + firstName + LastName보간에는 과부하가 걸리지 않기 때문에

스위프트 3가 개선되었습니다.자세한 내용은 컴파일러 속도를 늦추지 않고 여러 어레이를 병합하는 방법을 참조하십시오.그럼에도 불구하고+되어 있기 에 문자열이 긴 에는 문자열


옵션 사용(문제 발생 - 솔루션 사용 가능)

이 매우 심플한 프로젝트:

import UIKit

class ViewController: UIViewController {

    let p = Person()
    let p2 = Person2()

    func concatenatedOptionals() -> String {
        return (p2.firstName ?? "") + "" + (p2.lastName ?? "") + (p2.status ?? "")
    }

    func interpolationOptionals() -> String {
        return "\(p2.firstName ?? "") \(p2.lastName ?? "")\(p2.status ?? "")"
    }

    func concatenatedNonOptionals() -> String {
        return (p.firstName) + "" + (p.lastName) + (p.status)
    }

    func interpolatedNonOptionals() -> String {
        return "\(p.firstName) \(p.lastName)\(p.status)"
    }
}


struct Person {
    var firstName = "Swift"
    var lastName = "Honey"
    var status = "Married"
}

struct Person2 {
    var firstName: String? = "Swift"
    var lastName: String? = "Honey"
    var status: String? = "Married"
}

함수의 컴파일 시간은 다음과 같습니다.

21664.28ms  /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:16:10 instance method concatenatedOptionals()
2.31ms  /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:20:10 instance method interpolationOptionals()
0.96ms  /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:24:10 instance method concatenatedNonOptionals()
0.82ms  /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:28:10 instance method interpolatedNonOptionals()

「 」의 긴지 주목해 .concatenatedOptionals empty.month.mpti.

이 문제는 다음 방법으로 해결할 수 있습니다.

let emptyString: String = ""
func concatenatedOptionals() -> String {
    return (p2.firstName ?? emptyString) + emptyString + (p2.lastName ?? emptyString) + (p2.status ?? emptyString)
}

에 정리되어 있다88ms

가 컴파일러를입니다.""String사실...

에 「이것이 표시된다」라고 됩니다.?? 프로토콜을 준수하는 모든 유형을 루핑해야 합니다.이 프로토콜이 기본값이 될 수 있는 유형을 찾을 때까지String : ★★★★★★★★★★★★★★★★★★」emptyString하드코드 되어 있다String는 모든 의 호환성을 가진 컴파일러를 ExpressibleByStringLiteral

컴파일 시간을 기록하는 방법에 대해서는, 이쪽 또는 여기를 참조해 주세요.


SO에 관한 Rob Napier의 기타 유사한 답변:

문자열 추가 구축에 시간이 오래 걸리는 이유는 무엇입니까?

컴파일러 속도를 늦추지 않고 여러 어레이를 통합하는 방법

Swift Array에 빌드 시간을 길게 하는 기능이 포함되어 있습니다.

무슨 말을 해도 이건 말도 안 돼! :)

여기에 이미지 설명 입력

하지만 이것은 쉽게 지나간다.

return "\(year) \(month) \(dayString) \(hour) \(min) \(weekDay)"

저도 비슷한 문제가 있었습니다.

expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions

Xcode 9.3 행은 다음과 같습니다.

let media = entities.filter { (entity) -> Bool in

이렇게 바꾼 후:

let media = entities.filter { (entity: Entity) -> Bool in

모든 게 잘 풀렸어요

아마도 Swift 컴파일러가 코드 주변에서 데이터 유형을 추론하는 것과 관련이 있을 것입니다.

좋은 소식 - 이것은 곧 출시될 Xcode 13에서 수정될 것 같습니다.

이 일로 레이더 보고서를 제출했어요

http://openradar.appspot.com/radar?id=4962454186491904 https://bugreport.apple.com/web/ ? problem ID = 39206436

...그리고 애플은 이것이 수정되었다고 방금 확인했다.

복잡한 표현과 Swift로 모든 사례를 테스트했습니다.UI 코드와 Xcode 13에서는 모든 것이 정상적으로 동작하고 있는 것 같습니다.

Alex님, 기다려 주셔서 감사합니다.또, 피드백을 주셔서 감사합니다.이 문제는 해결되었다고 생각합니다.최신 Xcode 13 베타 2 릴리스로 테스트하고 https://feedbackassistant.apple.com에 로그인하거나 피드백 어시스턴트 앱을 사용하여 피드백 보고서를 업데이트하십시오.

언급URL : https://stackoverflow.com/questions/29707622/swift-compiler-error-expression-too-complex-on-a-string-concatenation

반응형