2015-08-11 9 views
5

मैं सेट का उप-वर्ग बनाने की कोशिश कर रहा हूं, और चूंकि मैं इसे केवल विस्तार से नहीं बढ़ा सकता, इसलिए मैं इसकी कार्यक्षमता को लपेट रहा हूं।Symbol.iterator को कैसे कार्यान्वित करें?

मैं Symbol.iterator विधि को लागू करने की कोशिश कर रहा हूं, लेकिन प्रवाह में से कोई भी नहीं है।

/* @flow */ 
class CSet<T> { 
    _set: Set<T>; 
    [Symbol.iterator](): Iterator<T> { 
     return this._set[Symbol.iterator]; 
    } 
} 

var a: CSet = new CSet(); 
for(var b of a){ 

} 

core.js:309:5,29: property @@iterator 
Property not found in 
test.js:2:7,10: CSet 

test.js:4:2,6:2: 
computed property keys not supported 

दूसरा त्रुटि एक समझौते के रूप में विशाल के बाद से मैं आसानी से इसे दबाने कर सकते हैं नहीं है:

इस कोड है कि मैं है। मैं सोच रहा हूं कि क्या मैं बस कुछ गलत कर रहा हूं।

उत्तर

5

देख क्योंकि प्रवाह नहीं है वर्तमान में प्रतीकों के लिए सामान्य समर्थन है, जिस तरह से यह Symbol.iterator का प्रतिनिधित्व करता है हैकी और मूल रूप से पूर्व है अब के लिए यूज़रस्पेस में iterators को परिभाषित करने की क्षमता (अपने समर्थन केवल पुस्तकालय परिभाषाओं में काम करता है) :(vents

विशेष रूप से प्रवाह की उम्मीद एक iterable उन पर एक @@iterator संपत्ति (जो निश्चित रूप से एक वैध संपत्ति नाम नहीं दे रहा है कि - लेकिन इस लाइब्रेरी परिभाषाओं में समर्थन प्राप्त करने के लिए एक अस्थायी हैक था)।

तो उचित प्रतीक समर्थन भूमि तक, एक समाधान के लिए यहाँ आपका सर्वश्रेष्ठ दांव इस मॉड्यूल प्रवाह की समझ के लिए यह @@iterator संपत्ति का उपयोग करता है के लिए एक पुस्तकालय परिभाषा बनाने के लिए होगा:

// RealModule.js 
export class CSet { 
    [Symbol.iterator]() { 
     return this._set[Symbol.iterator]; 
    } 
} 

// RealModule.FlowLibDef.js 
declare module RealModule { 
    declare class CSet<T> { 
     _set: Set<T>; 
     @@iterator(): Iterator<T>; 
    } 
} 
0

इस जावास्क्रिप्ट कोड की कोशिश

// module -- start 

let map = new WeakMap(); 

class Foo { 
    constructor(any) { 
    map.set(this, new Set(any)); 
    } 
    values() { 
    return map.get(this).values(); 
    } 
    [Symbol.iterator]() { 
    return this.values(); 
    } 
} 

// module -- end 


for(let item of new Foo([1,2,3])) { 
    console.log(item); 
} 

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
  2. sandbox
+0

मेरा बुरा, मुझे और अधिक विशिष्ट होना चाहिए। फ्लो के संबंध में यह ठीक तरह से जांच प्रकार नहीं है। प्रवाह मान() फ़ंक्शन के लिए सेट पर विचार नहीं करता है। – Kyle

1

मैं लिख सकते हैं और अपने पूरे वर्ग के लिए एक समानांतर libdef बनाए रखने के लिए जरूरत के बिना एक चाल आप iterable के रूप में एक उपयोगकर्ता परिभाषित वर्ग निशान देता है कि मिल गया है,।

कुंजी एक समर्पित सुपर क्लास कि [Symbol.iterator]() लागू करता है लिखते हैं, और सिर्फ इतना है कि सुपर क्लास के लिए एक libdef प्रदान करना है:

// IterableBase.js 
export default class IterableBase { 
    [Symbol.iterator]() { 
    return this._Symbol_iterator(); 
    } 
} 
// IterableBase.js.flow 
// @flow 
declare class IterableBase<T> { 
    @@iterator(): Iterator<T>; 
} 
export default IterableBase; 

अब आप अपने कस्टम वर्ग IterableBase का विस्तार करने और विकल्प को लागू कर सकते हैं विधि का नाम:

// RealModule.js 
// @flow 
import IterableBase from './IterableBase'; 

class CSet<T> extends IterableBase<T> { 
    _Symbol_iterator(): Iterator<T> { 
    ... 
    } 
} 

यह स्पष्ट रूप से अभी भी एक हैक है, बी यह विकल्प से आसान और सुरक्षित होना चाहिए।

2
// @flow 
class MyCollection<T> { 
    /*:: @@iterator(): Iterator<T> { return ({}: any); } */ 

    // $FlowFixMe: computed property 
    [Symbol.iterator](): Iterator<T> { 
     // NOTE: this could just as easily return a different implementation 
     return new MyIterator(this); 
    } 
} 

class MyIterator<+T> { 
    /*:: @@iterator(): Iterator<T> { return (this: any); } */ 

    // $FlowFixMe: computed property 
    [Symbol.iterator](): Iterator<T> { 
     return this; 
    } 

    next(): IteratorResult<T, void> { 
     return { done: false, value: someT }; 
     // or return { done: true, value: undefined }; 
    } 
} 

for (const value of new MyCollection()) { 
    console.log(value); 
} 

कारण यह काम करता है कि प्रवाह की व्याख्या है /*:: code */ है जैसे कि यह, स्रोत में प्रवाह कोड थे सिवाय इसके कि यह क्रम में बाहर टिप्पणी की है इसलिए वास्तव में कोड को प्रभावित नहीं करता।

प्रवाह आंतरिक रूप से, @@iterator विधि के बारे में जानता है के बावजूद यह मान्य JavaScript नहीं किया जा रहा है, इस प्रकार हम इसे मौजूदा, एक Iterator<T> लौटने वाला, और एक मूल्य है कि यह काम करता है के लिए (any के रूप में अर्थात एक खाली वस्तु डाली) लौटने के रूप में परिभाषित करते हैं।

गणना की गई संपत्ति विधि को प्रवाह द्वारा पूरी तरह से अनदेखा किया जाता है, जैसे कि यह बिल्कुल परिभाषित नहीं किया गया था। यह महत्वपूर्ण है कि आप वास्तव में विधि से वैध Iterator<T> वापस कर दें, अन्यथा चीजें रनटाइम पर टूट जाएंगी।

संबंधित मुद्दे