Dart getter返回枚举name属性时与setter类型不兼容报错问题
问题描述
实现parity(奇偶校验)相关逻辑时,通过enum.enum_entry.name属性提取枚举项对应的字符串值返回,触发类型不兼容报错。
相关代码
枚举定义与getter实现
enum SerialPortParity { none, even, odd, mark, space, } int _parity = UsbPort.PARITY_NONE; String get parity { switch (_parity) { case UsbPort.PARITY_NONE: return SerialPortParity.none.name; case UsbPort.PARITY_EVEN: return SerialPortParity.even.name; case UsbPort.PARITY_ODD: return SerialPortParity.odd.name; case UsbPort.PARITY_MARK: return SerialPortParity.mark.name; case UsbPort.PARITY_SPACE: return SerialPortParity.space.name; default: return SerialPortParity.none.name; } }
报错信息
The return type of getter 'parity' is 'String' which isn't a subtype of the type 'SerialPortParity' of its setter 'parity'. Try changing the types so that they are compatible.
对应setter实现
set parity(SerialPortParity parity) { switch (parity) { case SerialPortParity.none: _parity = UsbPort.PARITY_NONE; break; case SerialPortParity.even: _parity = UsbPort.PARITY_EVEN; break; case SerialPortParity.odd: _parity = UsbPort.PARITY_ODD; break; case SerialPortParity.mark: _parity = UsbPort.PARITY_MARK; break; case SerialPortParity.space: _parity = UsbPort.PARITY_SPACE; break; default: // 无操作 break; } }
报错原因
Dart语法规定,同名getter和setter必须类型兼容:如果setter的入参类型为SerialPortParity,对应getter的返回值类型必须是SerialPortParity或其子类。当前实现中getter返回值定义为String,和setter入参类型不匹配,因此编译器抛出错误。
解决方案
根据实际业务需求二选一即可,优先推荐第一种方案:
方案1:对外暴露枚举类型,单独提供字符串名称获取能力
将getter返回类型修改为SerialPortParity,直接返回枚举值而非.name字符串;如果业务场景需要用到字符串格式的枚举名称,单独新增一个getter获取即可。该方案保留了枚举的类型检查能力,避免非法入参导致运行时异常,是Dart枚举使用的标准实践。
修正后的getter代码:SerialPortParity get parity { switch (_parity) { case UsbPort.PARITY_NONE: return SerialPortParity.none; case UsbPort.PARITY_EVEN: return SerialPortParity.even; case UsbPort.PARITY_ODD: return SerialPortParity.odd; case UsbPort.PARITY_MARK: return SerialPortParity.mark; case UsbPort.PARITY_SPACE: return SerialPortParity.space; default: return SerialPortParity.none; } } // 需要字符串名称时单独调用该属性 String get parityName => parity.name;方案2:
parity属性直接对外暴露字符串类型
将setter的入参类型修改为String,在setter内部完成字符串到枚举值、再到底层USB端口常量的转换。该方案类型安全性较差,传入非法字符串时会触发运行时错误,非必要不选择。
参考实现:set parity(String parityName) { final parity = SerialPortParity.values.byName(parityName); switch (parity) { case SerialPortParity.none: _parity = UsbPort.PARITY_NONE; break; case SerialPortParity.even: _parity = UsbPort.PARITY_EVEN; break; case SerialPortParity.odd: _parity = UsbPort.PARITY_ODD; break; case SerialPortParity.mark: _parity = UsbPort.PARITY_MARK; break; case SerialPortParity.space: _parity = UsbPort.PARITY_SPACE; break; } }
内容的提问来源于stack exchange,提问作者Dark Sorrow
相关产品推荐
相关产品推荐

