有没有办法在通用地图中使用 Streamcontroller?
Is there any way to use Streamcontroller in generic map?
更新评论
- 我发现包的行为与我正在尝试的行为几乎相同。
尝试
event_bus
package
原问题
我正在尝试制作一个状态广播器,它通过单一路径向听众广播一些价值。
并且想使用泛型来减少重复的逻辑。
以下是我正在尝试的。
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{
StudyTimerStatus: StreamController<StudyTimerStatus?>.broadcast(),
};
void notify<T>(T value) => _sinkMap[T]?.add(value);
StreamSubscription<T> listen<T>(void Function(T) onData) {
return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
}
}
但是当我运行这段代码时,运行时间错误出现在(_sinkMap[T] as StreamController<T>)
。
The following _CastError was thrown building Builder:
type '_AsyncBroadcastStreamController<StudyTimerStatus?>' is not a subtype of type 'StreamController' in type cast
我该如何解决这个问题?
如果能达到我想要的目标(广播数据),改代码就好了。
我也试过省略向上转换,但是编译错误来了。
return _sinkMap[T].stream.listen(onData);
A value of type 'StreamSubscription' can't be returned from the method 'listen' because it has a return type of 'StreamSubscription'
The argument type 'void Function(T)' can't be assigned to the parameter type 'void Function(dynamic)?
我认为这应该可以满足您的要求。
如果您使用 listen<T>()
订阅,那么您应该将类型 T
的相应值传递给 notify
。
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{};
void notify<T>(T value) {
_sinkMap[T] ??= StreamController<T>.broadcast();
_sinkMap[T]?.add(value);
}
StreamSubscription<T> listen<T>(void Function(T) onData) {
_sinkMap[T] ??= StreamController<T>.broadcast();
return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
}
}
void main() {
final broadcaster = StateBroadcaster();
broadcaster.listen<int>((v) => print('int: $v'));
broadcaster.listen<String>((v) => print('String: $v'));
broadcaster.notify(1);
broadcaster.notify('a');
broadcaster.notify(2);
broadcaster.notify('b');
broadcaster.notify(3);
broadcaster.notify('c');
}
如果您想在 _sinkMap
中定义键值对而不是根据需要创建 key/value 对,这应该是可行的,但是如果您尝试使用地图中未预定义的键。
另外,您需要决定流值是否应该可以为空。如果您希望它们可以为空,则需要在 listen
.
中的类型中添加一个 ?
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{
StudyTimerStatus: StreamController<StudyTimerStatus?>.broadcast(),
};
void notify<T>(T value) => _sinkMap[T]?.add(value);
StreamSubscription<T?> listen<T>(void Function(T) onData) {
return (_sinkMap[T] as StreamController<T?>).stream.listen(onData);
}
}
如果您不希望它们可以为空,则需要从 _sinkMap
中的类型中删除 ?
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{
StudyTimerStatus: StreamController<StudyTimerStatus>.broadcast(),
};
void notify<T>(T value) => _sinkMap[T]?.add(value);
StreamSubscription<T> listen<T>(void Function(T) onData) {
return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
}
}
更新评论
- 我发现包的行为与我正在尝试的行为几乎相同。
尝试
event_bus
package
原问题
我正在尝试制作一个状态广播器,它通过单一路径向听众广播一些价值。 并且想使用泛型来减少重复的逻辑。
以下是我正在尝试的。
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{
StudyTimerStatus: StreamController<StudyTimerStatus?>.broadcast(),
};
void notify<T>(T value) => _sinkMap[T]?.add(value);
StreamSubscription<T> listen<T>(void Function(T) onData) {
return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
}
}
但是当我运行这段代码时,运行时间错误出现在(_sinkMap[T] as StreamController<T>)
。
The following _CastError was thrown building Builder: type '_AsyncBroadcastStreamController<StudyTimerStatus?>' is not a subtype of type 'StreamController' in type cast
我该如何解决这个问题?
如果能达到我想要的目标(广播数据),改代码就好了。
我也试过省略向上转换,但是编译错误来了。
return _sinkMap[T].stream.listen(onData);
A value of type 'StreamSubscription' can't be returned from the method 'listen' because it has a return type of 'StreamSubscription'
The argument type 'void Function(T)' can't be assigned to the parameter type 'void Function(dynamic)?
我认为这应该可以满足您的要求。
如果您使用 listen<T>()
订阅,那么您应该将类型 T
的相应值传递给 notify
。
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{};
void notify<T>(T value) {
_sinkMap[T] ??= StreamController<T>.broadcast();
_sinkMap[T]?.add(value);
}
StreamSubscription<T> listen<T>(void Function(T) onData) {
_sinkMap[T] ??= StreamController<T>.broadcast();
return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
}
}
void main() {
final broadcaster = StateBroadcaster();
broadcaster.listen<int>((v) => print('int: $v'));
broadcaster.listen<String>((v) => print('String: $v'));
broadcaster.notify(1);
broadcaster.notify('a');
broadcaster.notify(2);
broadcaster.notify('b');
broadcaster.notify(3);
broadcaster.notify('c');
}
如果您想在 _sinkMap
中定义键值对而不是根据需要创建 key/value 对,这应该是可行的,但是如果您尝试使用地图中未预定义的键。
另外,您需要决定流值是否应该可以为空。如果您希望它们可以为空,则需要在 listen
.
?
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{
StudyTimerStatus: StreamController<StudyTimerStatus?>.broadcast(),
};
void notify<T>(T value) => _sinkMap[T]?.add(value);
StreamSubscription<T?> listen<T>(void Function(T) onData) {
return (_sinkMap[T] as StreamController<T?>).stream.listen(onData);
}
}
如果您不希望它们可以为空,则需要从 _sinkMap
?
import 'dart:async';
class StateBroadcaster {
final _sinkMap = <Type, StreamController<dynamic>>{
StudyTimerStatus: StreamController<StudyTimerStatus>.broadcast(),
};
void notify<T>(T value) => _sinkMap[T]?.add(value);
StreamSubscription<T> listen<T>(void Function(T) onData) {
return (_sinkMap[T] as StreamController<T>).stream.listen(onData);
}
}