Использовать метод в пространстве имен не работает [дублировать]

Отчет об ошибке, поданный OP:

Что было разрешено (исправлено для овладения 3 января 2017 г.), и, следовательно, больше не будет проблемой в предстоящем Swift 3.1.


Это кажется ошибкой (не присутствует в Swift 2.2, всего 3.0), связанный со случаем:

  • Использование оператора принудительной разворачивания (!) для не менее 3 членов выражения (проверено с использованием, по меньшей мере, 2 основных операторов, например + или -).
  • По какой-то причине, учитывая вышеизложенное, Swift испортил вывод типа выражения (в частности, для самих членов x! в выражении).

Для всех приведенных ниже примеров пусть:

let a: String? = "a"
let b: String? = "b"
let c: String? = "c"

Присутствует ошибка:

// example 1
a! + b! + c!
    /* error: ambiguous reference to member '+' */

// example 2
var d: String =  a! + b! + c!
    /* error: ambiguous reference to member '+' */

// example 3
var d: String? =  a! + b! + c!
    /* error: cannot convert value of type 'String' 
       to specified type 'String?' */

// example 4
var d: String?
d =  a! + b! + c!
    /* error: cannot assign value of type 'String' 
       to specified type 'String?' */

// example 5 (not just for type String and '+' operator)
let a: Int? = 1
let b: Int? = 2
let c: Int? = 3
var d: Int? = a! + b! + c!
    /* error: cannot convert value of type 'Int' 
       to specified type 'Int?' */
var e: Int? = a! - b! - c! // same error

Ошибка отсутствует:

/* example 1 */
var d: String? = a! + b!

/* example 2 */
let aa = a!
let bb = b!
let cc = c!
var d: String? = aa + bb + cc
var e: String = aa + bb + cc

/* example 3 */
var d: String? = String(a!) + String(b!) + String(c!)

Однако, поскольку это Swift 3.0-dev, я не уверен, что это действительно «ошибка», а также то, что политика сообщая «ошибки» в еще не-производственной версии кода, но, возможно, вы должны на этот раз подать радар для этого.

Что касается ответа на ваш вопрос, как обойти эту проблему:

  • использовать, например, промежуточные переменные, как в Ошибка отсутствует: пример 2 выше,
  • или явно сказать Swift все члены в трехчленном выражении являются строками, как в Ошибка отсутствует: Пример 3 выше,
  • или, еще лучше, используйте безопасную разворачивание вашего дополнительного, например используя необязательное связывание :
    var d: String? = nil
    if let a = a, b = b, c = c {
        d = a + b + c
    } /* if any of a, b or c are 'nil', d will remain as 'nil';
         otherwise, the concenation of their unwrapped values   */
    

3
задан wilx 27 March 2013 в 09:27
поделиться

4 ответа

Предположим, вы объявили функцию:

int Random();

И используйте ее:

int main()
{
   int n;
   n = Random();
}

Но реализуйте функцию Random после main. Или предположим, что функция Random определена в некотором заголовке. Вам нужно указать компилятору, что Random - это функция, реализованная в каком-то другом исходном файле или в некоторой библиотеке.

Поэтому выражение, подобное:

T foo();

, всегда означает инструкцию для компилятора, что есть функция с именем foo, которая возвращает T. Он не может быть объектом типа T.

3
ответ дан Ajay 18 August 2018 в 19:42
поделиться

Он объявляет функцию f, которая не принимает никаких параметров и возвращает тип X. Это также известно как Most Vexing Parse в C ++. Это побочный результат того, как стандарт C ++ определяет правила интерпретации деклараций.

8
ответ дан Alok Save 18 August 2018 в 19:42
поделиться
  • 1
    +1. Однако это обычно называют просто «анализирующим анализом». Большую часть времени я видел «Самый неприятный синтаксический анализ». обратитесь к X f(X()). – Angew 27 March 2013 в 09:13
  • 2
    @Angew: Позвольте мне быть более конкретным, X f(X()) всегда классически обозначался как Most Vexing Parse , некоторые считают X f() столь же досадным, как и предыдущий, и считают его похожим и именем аналогично, некоторые считают X f() более предсказуемым как объявление функции, чем исходный разборный синтаксический анализ, и, следовательно, вообще не рассматривают его как Most vexing parse . Это скорее номенклатура, основанная на восприятии, чем стандартная терминология, и поэтому нет единообразия как таковой. Рад, что ты это придумал. Спасибо. – Alok Save 27 March 2013 в 09:19
  • 3
    @Angew - это смешно, после почти 20 лет разработки на C ++ я только что столкнулся с вчерашним анализом most . Думаю, до сих пор я никогда не пробовал эту конструкцию, и я ожидал, что она сработает, зная все о досадном анализе. – Crazy Eddie 27 March 2013 в 09:20

Объявление функции функции f

  X          f();
  ^          ^ function   
  return type 

функции f() не принимает аргументов и возвращает объект класса X.

, например, его определение может быть следующим:

class X{
   int i;
   // other definition
}

X f(){ 
    X x;
    // some more code
    return x; 
}  

В основном вы можете использовать как:

int main(){

 X a = f();
 int i = f().i;
}
2
ответ дан Grijesh Chauhan 18 August 2018 в 19:42
поделиться
  • 1
    Почему нам нужно что-то подобное? – Aryan 27 March 2013 в 09:03
  • 2
    @Aryan это просто похоже на int f(){ i = 10; return i;}, необходимо вернуть объект класса X в функцию вызова. @Ajay предоставил очень хороший пример. – Grijesh Chauhan 27 March 2013 в 09:05

Это функция, которая не принимает никаких аргументов и возвращает объект класса X

1
ответ дан Yogi 18 August 2018 в 19:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: