类型断言无效:无法将 os.Stdout 转换为接口类型 io.ReadWriter?

invalid type assertion: cannot convert os.Stdout to interface type io.ReadWriter?

我指的是 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是writer,这次转换为ReadWriter应该会触发运行时类型转换错误,但实际上是报编译错误

我想知道type assertion/conversion在什么情况下会在编译时失败,在什么情况下会在运行时失败?

您可以使用 io.ReadWriter(os.Stdout) 来做到这一点,因为您已经有一个指向结构的具体指针(或者也适用于结构)。

类型断言如v.(*SomeConcreteType)v实现一些接口并且你想将其转换为具体类型(struct/pointer...)时使用。您正在尝试以相反的方式进行操作,这就是编译器抱怨非接口类型的原因。

这没有任何意义,因为您唯一要做的就是限制可以调用 v2 的方法。您仍然可以将 v 传递给接受 io.ReadWriter 的方法,而无需在实现该接口时进行任何转换。

在您的代码中 v 是一个具体类型 *FILE 并且对于形式 i.(T) 的类型断言,i 必须是 interfaceT是type/interface,所以你的代码有编译错误

这应该做你除了但它不会触发运行时错误因为 os.Stdout 满足 io.ReadWriter 接口

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

under what condition it will fail in runtime

如果接口 i 没有 hold/Satisfy 类型 T 的要求,该语句将触发恐慌。

例如,这些语句将触发恐慌,因为类型为 *FILEos.Stdout 不满足 io.ByteScanner

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