You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Attempting to compile and run this code produces the following error:
Failed to build server:server:
bin/server.dart:7:29: Error: The argument type 'Utf8Decoder' can't be assigned to the parameter type 'StreamTransformer<Uint8List, dynamic>'.
- 'Utf8Decoder' is from 'dart:convert'.
- 'StreamTransformer' is from 'dart:async'.
- 'Uint8List' is from 'dart:typed_data'.
socket.transform(utf8.decoder).listen(print);
Tracing the documentation for Utf8Decoder, it is a StreamTransformer<List<int>, String>. The documentation for Socket transform has the signature transform<S>(StreamTransformer<Uint8List, S> streamTransformer) → Stream<S>. Uint8List is a subtype of List<int>.
Dart suggests the following cast utf8.decoder as StreamTransformer<Uint8List, dynamic> which satisfies the static type checker, but produces the following stack trace (excerpt) at runtime:
Unhandled exception:
type 'Utf8Decoder' is not a subtype of type 'StreamTransformer<Uint8List, dynamic>' in type cast
This is correct, because StreamTransformer<Uint8List, dyamic> is not a subtype of StreamTransformer<List<int>, String> rather it is the other way around.
If I change the code to the following, then it works fine even though Dart suggests the cast to List is unnecessary which it is not (or at least I couldn't figure it out):
It really should have been a function, Stream<T> Function(Stream<S>), which is contravariant in S.
(Today the class also has a cast method, but that most likely wouldn't have been necessary if it had just been a function type to begin with.)
So, this is working as well as possible with the current API, and won't get better unless we introduce contravariant type variables. (Or we can introduce an extension method on Stream<T>: Stream<R> mapStream<R>(Stream<R> Function(Stream<S>) convert) => convert(this);, so you can do .transform(utf8.decoder.bind) properly contravariantly.
But if we do get contravariant type parameters, StreamTransformer is top of the list of candidates.
General info
Project info
Process info
The Issue
The documentation for ServerSocket shows the basic example:
Attempting to compile and run this code produces the following error:
Tracing the documentation for Utf8Decoder, it is a
StreamTransformer<List<int>, String>
. The documentation for Socket transform has the signaturetransform<S>(StreamTransformer<Uint8List, S> streamTransformer) → Stream<S>
.Uint8List
is a subtype ofList<int>
.Dart suggests the following cast
utf8.decoder as StreamTransformer<Uint8List, dynamic>
which satisfies the static type checker, but produces the following stack trace (excerpt) at runtime:This is correct, because
StreamTransformer<Uint8List, dyamic>
is not a subtype ofStreamTransformer<List<int>, String>
rather it is the other way around.If I change the code to the following, then it works fine even though Dart suggests the cast to List is unnecessary which it is not (or at least I couldn't figure it out):
Documentation References
dart:io
Utf8Decoder
Uint8List
Socket
The text was updated successfully, but these errors were encountered: