You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter将List<int>转List<String>存SharedPreferences时遇类型转换错误

Flutter中List转List存储到SharedPreferences的类型转换错误解决

错误信息

Unhandled Exception: type 'String' is not a subtype of type 'int' in type cast

相关代码片段

处理List的初始代码:

else if (value is List<int>) {
          prefs.setStringList(
              "itemsToLoanCats", [...value.map((e) => e.toString())]);
        }

尝试的循环转换代码(存在语法错误):

List<String> encodedList = [];
for(int intValue in (value as List<int>)) {
  print(LOG + "intValue: $intValue");
  encodedList.add(int.parse(intValue).toString()); // 错误:int.parse参数应为String,此处intValue是int类型
}

完整saveToPrefs方法代码:

saveToPrefs(SharedPreferences prefs) {
  (this.toMap()).forEach((key, value) {
    if (value != null) {
      if (key == "dbProfilePicPath") {
        print("PERSON " + "should be saving dbProfilePicPath");
      }
      if (value is String) {
        prefs.setString(key, value);
      } else if (key == "position") {
        print("saveToPrefs converting GeoPoint...");
        double latitude = value['geopoint'].latitude;
        double longitude = value['geopoint'].longitude;
        prefs.set</think_never_used_51bce0c785ca2f68081bfa7d91973934>Double("latitude", latitude);
        prefs.setDouble("longitude", longitude);
      } else if (value is List<String>)
        prefs.setStringList(key, value);
      else if (value is double)
        prefs.setDouble(key, value);
      else if (value is int)
        prefs.setInt(key, value);
      else if (value is bool)
        prefs.setBool(key, value);
      else if (value is Map<String, String>) {
        List<String>? list = [];
        value.forEach((key, value) {
          list.add("$key:$value");
        });
        prefs.setStringList(key, list);
      } else if (value is Map<String, bool>) {
        List<String>? list = [];
        value.forEach((key, value) {
          list.add("$key:${value.toString()}");
        });
        prefs.setStringList(key, list);
      } else if (value is Map<String, dynamic>) {
        // 未实现存储逻辑
      } else if (value is List<int>) {
        value = value.cast<int>();
        print(LOG + 'This is claiming to be itemsToLoanCats: ${value.toString()}');
        prefs.setStringList("itemsToLoanCats", value.map((el) => el.toString()).toList());
      }
    }
  });
}

错误堆栈信息

I/flutter (16996): Person This is claiming to be itemsToLoanCats: [0]
I/flutter (16996): saveToPrefs converting GeoPoint...
E/flutter (16996): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'String' is not a subtype of type 'int' in type cast
E/flutter (16996): #0      _CastListBase.[] (dart:_internal/cast.dart:99:46)
E/flutter (16996): #1      ListMixin.elementAt (dart:collection/list.dart:78:33)
E/flutter (16996): #2      ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
E/flutter (16996): #3      StringBuffer.writeAll (dart:core-patch/string_buffer_patch.dart:96:19)
E/flutter (16996): #4      IterableBase.iterableToFullString (dart:collection/iterable.dart:268:14)
E/flutter (16996): #5      ListMixin.toString (dart:collection/list.dart:588:37)
E/flutter (16996): #6      Person.saveToPrefs.<anonymous closure> (package:meloan/model/person.dart:635:72)
E/flutter (16996): #7      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
E/flutter (16996): #8      Person.saveToPrefs (package:meloan/model/person.dart:593:20)
E/flutter (16996): #9      _PersonalDetailsScreenState._buildBody.<anonymous closure> (package:meloan/personal/edit_personal_details.dart:1231:30)
E/flutter (16996): #10     _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
E/flutter (16996): #11     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
E/flutter (16996): #12     TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
E/flutter (16996): #13     BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
E/flutter (16996): #14     BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:276:7)
E/flutter (16996): #15     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:163:27)
E/flutter (16996): #16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:464:20)
E/flutter (16996): #17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
E/flutter (16996): #18     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
E/flutter (16996): #19     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
E/flutter (16996): #20     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
E/flutter (16996): #21     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
E/flutter (16996): #22     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
E/flutter (16996): #23     _invoke1 (dart:ui/hooks.dart:167:13)
E/flutter (16996): #24     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
E/flutter (16996): #25     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)

问题原因

  1. 泛型类型检查失效:Dart运行时会擦除泛型参数,value is List<int>仅能判断value是List类型,无法验证列表内元素是否全为int。若value是混有String元素的List<dynamic>,该条件仍会返回true,后续value.cast<int>()生成的CastList<int>在遍历toString时,会触发元素类型转换错误。
  2. 循环变量修改导致类型混乱:在分支中直接修改forEach的循环参数value,将其赋值为cast后的列表,会干扰后续代码对变量类型的判断。
  3. 循环转换代码存在语法错误:int.parse(intValue)中intValue是int类型,而int.parse()要求传入String参数,这行代码本身会引发错误。

解决方案

1. 修正类型检查逻辑

替换原有的value is List<int>判断,先确认是List,再验证所有元素均为int,同时增加key判断确保仅处理目标列表:

else if (key == "itemsToLoanCats" && value is List && value.every((element) => element is int)) {

2. 使用局部变量存储转换后的列表

避免修改forEach循环参数,改用局部变量存储类型转换后的列表:

else if (key == "itemsToLoanCats" && value is List && value.every((element) => element is int)) {
  final List<int> intList = value.cast<int>();
  print(LOG + 'This is claiming to be itemsToLoanCats: ${intList.toString()}');
  // 将List<int>转为List<String>后存储
  prefs.setStringList(key, intList.map((el) => el.toString()).toList());
}

3. 修正循环转换代码的错误

若使用循环转换,直接调用intValue.toString()即可,无需多余的int.parse():

List<String> encodedList = [];
for (int intValue in (value as List<int>)) {
  print(LOG + "intValue: $intValue");
  encodedList.add(intValue.toString());
}
prefs.setStringList("itemsToLoanCats", encodedList);

4. 可选:用JSON序列化简化存储

若需存储复杂类型,可将List序列化为JSON字符串存储,读取时再反序列化:

// 存储
prefs.setString("itemsToLoanCats", json.encode(value));
// 读取
List<int> intList = List<int>.from(json.decode(prefs.getString("itemsToLoanCats") ?? "[]"));

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:40:25