утверждение неверного типа: невозможно преобразовать os.Stdout в интерфейс типа io.ReadWriter? - PullRequest
0 голосов
/ 19 января 2020

Я ссылаюсь на пример кода gopl, как показано ниже:

v := os.Stdout
v2 = v.(io.ReadWriter)

Но go 1.13 приведет к ошибке компиляции отчета:

invalid type assertion: v.(io.ReadWriter) (non-interface type *os.File on left)

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

Я sh, чтобы знать, в каких условиях тип утверждения / преобразования будет потерпеть неудачу во время компиляции, и при каких условиях он потерпит неудачу во время выполнения?

Ответы [ 2 ]

2 голосов
/ 19 января 2020

Вы можете использовать io.ReadWriter(os.Stdout), чтобы сделать это, поскольку у вас уже есть конкретный указатель на структуру (в качестве альтернативы также работает со структурами).

Утверждения типа, такие как v.(*SomeConcreteType), используются, когда v реализует некоторый интерфейс, и вы хотите преобразовать его в конкретный тип (struct / pointer ...). Вы пытаетесь сделать это наоборот, вот почему компилятор жалуется на неинтерфейсный тип.

Это на самом деле не имеет смысла, так как единственное, что вы делаете, это ограничивает методы, которые вы используете. можете позвонить на v2. Вы все еще можете передать v методу, который принимает io.ReadWriter без преобразования чего-либо, поскольку он реализует этот интерфейс.

1 голос
/ 19 января 2020

В вашем коде v - это конкретный тип *FILE, а для утверждения типа в форме i.(T), i должно быть interface, а T - это тип / интерфейс, поэтому ваш код компилируется error

Это должно делать то, что вы, но не вызовет ошибку времени выполнения, потому что os.Stdout удовлетворяет io.ReadWriter interface

var v interface{} = os.Stdout
v2 := v.(io.ReadWriter)

, при каких условиях он не будет работать во время выполнения

Если интерфейс i не поддерживает / удовлетворяет требованию для типа T, оператор вызовет pani c.

Например, эти операторы вызовут pani c, потому что os.Stdout с типом *FILE не удовлетворяет требованиям для io.ByteScanner

var v interface{} = os.Stdout
v2 := v.(io.ByteScanner)
...