मेरे पास एक नक्शा है जिसमें विभिन्न प्रकार और तार शामिल हैं:

const Map<Type, String> hiveTableNames = {
  BreakTimeDto: "breaktime",
  WorkTimeDto: "worktime"
};

और मैं इसके माध्यम से लूप करना चाहता हूं क्योंकि मैं प्रत्येक प्रकार के लिए एक फ़ंक्शन कॉल करना चाहता हूं जो एक प्रकार पैरामीटर लेता है:

Future<void> sendAll<T>(List item) async {
...
}

मेरा प्रयास forEach-loop का उपयोग करना था:

hiveTableNames.forEach((key, value) async {
        final box = await Hive.openBox(value);
        _helper.sendAll<key>(box.values.cast<key>().toList());
      });

लेकिन ऐप एक त्रुटि देता है: त्रुटि: 'कुंजी' एक प्रकार नहीं है।

ऐसा क्यों है? मैंने मानचित्र को प्रकारों को संग्रहीत करने के लिए घोषित किया और मेरी समझ से मैं इन प्रकारों को फ़ंक्शन में पास करता हूं।

0
niclassic 4 जिंदा 2021, 19:38
आपको एक वेरिएबल को cast मेथड में पास करने के बजाय क्लास टाइप key पास करना होगा।
 – 
Adnan Alshami
4 जिंदा 2021, 20:03
मैं यह कैसे करूँगा, इस तथ्य के कारण कि वर्ग प्रकार की कुंजी हमेशा अलग-अलग वर्ग प्रकार होती है, जैसा कि मानचित्र में देखा गया है?
 – 
niclassic
4 जिंदा 2021, 23:34
1
मेरा मानना ​​है कि जेनरिक संकलन समय पर हल हो जाते हैं; अन्यथा उस सामान्य प्रकार पर निर्भर तर्कों या वापसी मूल्यों की स्थिर प्रकार-जांच नहीं मिलेगी। इसलिए आप एक प्रकार के पैरामीटर के रूप में एक चर का उपयोग नहीं कर सकते हैं।
 – 
jamesdlin
5 जिंदा 2021, 10:03

1 उत्तर

सबसे बढ़िया उत्तर

डार्ट Type प्रकार के वास्तविक प्रकारों और वस्तुओं को अलग करता है। उत्तरार्द्ध प्रकार नहीं हैं, और प्रकारों के रूप में उपयोग नहीं किया जा सकता है, वे अधिक प्रकार के दर्पण की तरह हैं। एक Type वस्तु का उपयोग वास्तव में केवल दो चीजों के लिए किया जा सकता है: टोकन के रूप में dart:mirrors के साथ उपयोग करने के लिए और समानता के लिए तुलना करना (जो बहुत सरल प्रकारों को छोड़कर विशेष रूप से उपयोगी नहीं है)।

सामान्य कार्यों या कक्षाओं के लिए तर्क के रूप में उपयोग की जा सकने वाली एकमात्र चीजें वास्तविक शाब्दिक प्रकार या अन्य प्रकार के चर हैं।

आपके मामले में, आपके पास एक Type वस्तु है और आप संबंधित प्रकार को एक प्रकार के तर्क के रूप में उपयोग करना चाहते हैं। यह काम नहीं करेगा, Type ऑब्जेक्ट से वास्तविक प्रकार तक जाने का कोई तरीका नहीं है। यह एक जानबूझकर पसंद है, इसका मतलब है कि संकलक यह देख सकता है कि यदि स्रोत कोड में किसी प्रकार का उपयोग तर्क के रूप में कभी नहीं किया जाता है, तो यह कभी भी प्रकार पैरामीटर के लिए बाध्य नहीं होगा, इसलिए यदि आपके पास foo<T>(T value) => ... तो आप जानते हैं कि T कभी भी Bar नहीं होगा यदि Bar एक प्रकार के तर्क के रूप में नहीं आता है, something<Bar>(), प्रोग्राम में कहीं भी।

आपके मामले में, आप अधिक जटिल कुंजी ऑब्जेक्ट का उपयोग करके टाइप को एक प्रकार के रूप में के आसपास रखने के लिए क्या कर सकते हैं।

शायद:

class MyType<T> {
  const MyType();
  R use<R>(R Function<X>() action) => action<T>();
  int get hashCode => T.hashCode;
  bool operator==(Object other) => other is MyType && other.use(<S>() => T == S);
}

यह आपको एक प्रकार के रूप में प्रकार को संग्रहीत करने की अनुमति देता है:

final Map<MyType, String> hiveTableNames = {
  const MyType<BreakTimeDto>(): "breaktime",
  const MyType<WorkTimeDto>(): "worktime"
};

(मैं नक्शा const नहीं बना रहा हूं क्योंकि const नक्शे में ऐसी कुंजियां नहीं होनी चाहिए जो operator== को ओवरराइड करती हों)। फिर आप इसे इस प्रकार उपयोग कर सकते हैं:

hiveTableNames.forEach((key, value) async {
  final box = await Hive.openBox(value);
  key.use(<K>() => 
    _helper.sendAll<K>([for (var v in box.values) v as K]);
}

(यदि आप सभी के लिए अपने मानचित्र का उपयोग कर रहे हैं, कुंजी/मान जोड़े को पुनरावृत्त कर रहे हैं, तो यह वास्तव में केवल जोड़े की एक सूची है, मानचित्र नहीं, इसलिए मुझे लगता है कि आप इसे लुकअप के लिए उपयोग कर रहे हैं, यही कारण है कि MyType ओवरराइड operator==)।

सामान्य तौर पर, आपको किसी भी चीज़ के लिए Type वस्तुओं का उपयोग करने से बचना चाहिए, वे बहुत कम ही किसी भी काम के लिए सही उपकरण होते हैं।

1
lrn 7 जिंदा 2021, 13:02