Swift не может преобразовать тип выражения ‘Void’ в тип ‘String!’

#swift

#swift

Вопрос:

Я пытаюсь использовать фрагмент примера кода из этой статьи NSHipster, примерно на полпути вниз по странице.

 var inputStream: NSInputStream
var outputStream: NSOutputStream

NSStream.getStreamsToHostWithName(hostname: "nshipster.com",
                                      port: 5432,
                               inputStream: amp;inputStream,
                              outputStream: amp;outputStream)
 

Я поместил это на игровую площадку вместе с import Foundation , и я получаю эту ошибку.

 Playground execution failed: error: <REPL>:6:10: error: cannot convert the expression's type 'Void' to type 'String!'
NSStream.getStreamsToHostWithName(hostname: "nshipster.com",
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

Эта ошибка указывает на первый аргумент, который явно имеет тип String! , а не Void нет .

Я немного изменил код, чтобы извлечь определения из вызова метода. Вот полная игровая площадка:

 import Foundation

var inputStream: NSInputStream
var outputStream: NSOutputStream

let host = "nshipster.com"
let port = 5432
NSStream.getStreamsToHostWithName(hostname: host,
    port: port,
    inputStream: amp;inputStream,
    outputStream: amp;outputStream)
 

Теперь ошибка указывает на третий аргумент, предположительно удовлетворяющий первым двум.

 Playground execution failed: error: <REPL>:10:18: error: cannot convert the expression's type 'Void' to type 'inout NSInputStream'
inputStream: amp;inputStream,
             ^~~~~~~~~~~~
 

Я не могу понять, как я могу извлечь AutoreleasingUnsafePointer переменные для InputStream и OutputStream таким же образом, но я думаю, что исходный пример кода должен работать. Это ошибка в моем (и Mattt’s) коде или ошибка в Swift?

РЕДАКТИРОВАТЬ: я отправил запрос на извлечение с исправленным кодом для NSHipster.

Ответ №1:

Ну, короткий ответ заключается в том, что вам нужно передавать опции вместо необязательных (для всего, что ищет объекты inout)

 var inputStream:NSInputStream?
var outputStream:NSOutputStream?

NSStream.getStreamsToHostWithName("nshipster.com", port: 5432, inputStream: amp;inputStream, outputStream: amp;outputStream)
 

Тем не менее, он компилируется сейчас, но не запускается, потому что NSStream, по-видимому, не имеет метода getStreamsToHostWithName (по крайней мере, в импортируемом мной Foundation), Не обращайте внимания на это, это вызов только для iOS, поэтому он не работал с Playground, установленным на OSX. Кажется, все в порядке с его настройкой на iOS.

Комментарии:

1. Спасибо, изменение типов на optionals и удаление дополнительного hostname: индикатора исправляет это. Использование инспектора файлов для установки playground на iOS запускает код (хотя сокет, очевидно, не подключается, поскольку на этом порту ничего не работает).

2. Да, в общем, любой inout NSObject, который вы получаете из CF или Cocoa, должен быть необязательным.

3. Добавлено тихо в OS X 10.10 и iOS 8.0 (void)getStreamsToHostWithName:(NSString *)hostname port:(NSInteger)port inputStream:(NSInputStream **)inputStream outputStream:(NSOutputStream **)outputStream NS_AVAILABLE(10_10, 8_0);