У меня есть функция с этой подписью, написанной в проекте Swift в Xcode 7.3.1:

func DLog<T>(@autoclosure object: () -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
}

Компилятор жалуется на Generic parameter 'T' could not be inferred для этого вызова:

DLog({ var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; })

Когда я пытаюсь предоставить тип, он жалуется Cannot explicitly specialize a generic function:

DLog<String>({ var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; })

Я перепробовал еще несколько подходов, но компилятор не удовлетворил ничего. Я также не смог найти подсказку, как решить это дело.

Как построить текст внутри аргумента () => T и правильно передать его функции?

1
alik 24 Апр 2017 в 21:29

2 ответа

Лучший ответ

Компиляция не удалась из-за атрибута @autoclosure. Когда вы передаете некоторое выражение в функцию, которая принимает @autoclosure, компилятор создает замыкание без параметров, которое возвращает результат этого выражения. Итак, когда вы передаете { var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; }, компилятор создает замыкание, возвращающее замыкание, возвращающее строку.

Чтобы это исправить, вы можете добавить () в конец выражения:

DLog({ () -> String in var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; }())

Или упростить выражение до простого вызова метода, например

DLog(outlines.reduce("Returning output list\n") { $0 + $1.debugDescription + "\n"; })
2
Maxim Kosov 24 Апр 2017 в 20:33

Я не знаю, почему это вызывает его, но при компиляции в swift 3 появляется это сообщение об ошибке:

Невозможно определить тип возврата сложного замыкания; добавить явный тип для устранения неоднозначности

Поэтому я попытался явно добавить тип возврата для замыкания:

DLog(
    { () -> String in 
        var text = "Returning output list\n" 
        for outline in outlines { 
            text = text + outline.debugDescription + "\n"; 
        } 
        return text 
    }
)

И это сработало.

0
Sweeper 24 Апр 2017 в 19:15
43595291