我正在尝试从 Dart/Flutter 应用程序中的 Rest API 解析数据。JSON 包含一个data在根处调用的字段,其中包含一个Words列表。我想List<Word>从这个 JSON 中得到一个。我已经有以下代码:
Map<String, dynamic> jsonMap = json.decode(jsonString);
List<Word> temp = jsonMap['data']
.map((map) => map as Map<String, dynamic>)
.map((Map<String, dynamic> map) => Word.fromJson(map)).toList(); // map to List<Word>
Run Code Online (Sandbox Code Playgroud)
Word.fromJson 具有以下签名:
Word.fromJson(Map<String, dynamic> json)
Run Code Online (Sandbox Code Playgroud)
最后调用map给出了以下错误:
type 'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'
Run Code Online (Sandbox Code Playgroud)
根据我的理解,调用 tomap((map) => map as Map<String, dynamic>)应该将 the 转换List<dynamic>为 a List<Map<String, dynamic>>,所以我对为什么会收到错误感到困惑。
任何建议表示赞赏。
我正在package:dioFlutter Web 应用程序中使用。
然而,每当我发送 POST 请求时,它就会更改为 OPTIONS 请求。发出 API 请求的函数如下所示:
Future<LoginResponse> login(LoginRequest request) async {
final dio = Dio(BaseOptions(baseUrl: "http://localhost:8000"));
final response = await dio.post("/login", data: request.toJson());
return LoginResponse.fromJson(jsonDecode(response.data));
}
Run Code Online (Sandbox Code Playgroud)
此代码将OPTIONS请求发送到http://localhost:8000/login. 如果我将该端点添加到我的服务器,它就可以工作。
如果我手动从邮递员发送 POST 请求,它也可以工作。
如果我将此代码更改为其他方法(例如dio.delete(...)),它也会映射到OPTIONS请求。
为什么要dio重写我的请求?
我正在创建一个宏来为某些基本类型生成瘦包装器,例如语法:
wrapper!(String => Email);
Run Code Online (Sandbox Code Playgroud)
会扩展到大致类似:
struct Email {
inner: String,
}
impl Email {
// some boilerplate-y stuff
}
Run Code Online (Sandbox Code Playgroud)
但是,我希望这些类型在适当的情况下实现一些 stdlib 特征(例如Eq、Clone、Copy等。特别是,Copy在这里引起问题。
我希望包装器类型是Copy内部类型Copy(类似于#[derive]工作方式),但是如果我在生成的特征上放置派生实现,如果不兼容,我会收到错误:
macro_rules! wrapper {
($inner:ty => $name:ident) => {
#[derive(Copy)]
struct $name {
inner: $inner
}
}
}
wrapper!(i64 => Version); // works fine
wrapper!(String => Email); // Error, String is not Copy
Run Code Online (Sandbox Code Playgroud)
我宁愿它只是“没有尝试实现Copy”,而不是使用非复制类型时出现编译时错误,但我不确定如何在宏中表达这一点。
另一种不成功的尝试如下:
// inside macro
impl Copy for $name …Run Code Online (Sandbox Code Playgroud) 我可以使用该#[must_use]属性将函数标记为具有必须使用或显式忽略的返回值:
#[must_use]
fn plain() -> i32 {
1
}
fn main() {
plain(); // warning
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我想更改我的函数,使其现在返回 a Result,我不能这样做:
#[must_use]
fn result() -> Result<i32, ()> {
Ok(1)
}
fn main() {
result().unwrap();
}
Run Code Online (Sandbox Code Playgroud)
因为对的调用.unwrap()算作“使用”,并且该#[must_use]属性应用于整个Result.
有没有办法#[must_use]也适用于内部类型?本质上我想确保i32不会意外地被分号“吃掉”。
我有一个额外的限制,即我无法更改此函数的公共 API,因此我无法让它返回 aResult<MustUse<i32>, ()>或类似的内容。