The following code (play):
func main() {
buf := bytes.NewBuffer(make([]byte, 0))
rw := bufio.NewReadWriter(bufio.NewReader(buf), bufio.NewWriter(buf))
var r *bufio.Writer
r = rw
}
Gives the following compile-time error:
cannot use rw (type *bufio.ReadWriter) as type *bufio.Writer in assignment
What I expected is use a struct as a nested struct type. But if I declare r
as io.Reader
, this will be ok, so should I move to interface?
bufio.NewReadWriter()
returns a concrete type, a pointer to a struct
and bufio.Writer
is also a concrete type, a struct
. Neither *ReadWriter
and *bufio.Writer
is an interface!
In Go there is no automatic type conversion, you cannot assign a value of different concrete type to a variable.
Since bufio.ReadWriter
embeds *bufio.Writer
, you can simply refer to it and use that in the assignment:
var r *bufio.Writer
r = rw.Writer
Or you can declare r
to be an io.Writer
(it is an interface type) so that you can assign rw
to it because rw
implements io.Writer
:
var r io.Writer
r = rw
Although I don't think creating r
in this case is particularly useful because whenever you would use r
you could also use rw
.
Check out Go spec: Assignability:
A value
x
is assignable to a variable of typeT
("x
is assignable toT
") in any of these cases:
x
's type is identical toT
.x
's typeV
andT
have identical underlying types and at least one ofV
orT
is not a named type.T
is an interface type andx
implementsT
.x
is a bidirectional channel value,T
is a channel type,x
's typeV
andT
have identical element types, and at least one ofV
orT
is not a named type.x
is the predeclared identifiernil
andT
is a pointer, function, slice, map, channel, or interface type.x
is an untyped constant representable by a value of typeT
.
None of the cases apply to your code, so it is an invalid assignment.
When r
is declared to be io.Writer
, it is the the following case and therefore it is valid:
T
is an interface type andx
implementsT
.
Different type can't assign, GO do not support extension.