6

क्यों स्काला संकलक इस समारोह परिभाषा के बारे में खुश नहीं है मैं एक कठिन समय समझ कर रहा हूँ रिटर्न:समारोह जो सामान्य रूप से एक प्रकार लेता है और एक ही प्रकार

scala> def trimNonWordCharacters[T <: Iterable[String]](items: T): T = 
    items map { _.replaceAll("\\W", "") } 
<console>:5: error: type mismatch; 
found : Iterable[java.lang.String] 
required: T 
     def trimNonWordCharacters[T <: Iterable[String]](items: T): T = items map { _.replaceAll("\\W", "") } 
:

def trimNonWordCharacters[T <: Iterable[String]](items: T): T = 
    items map { _.replaceAll("\\W", "") } 

यहाँ REPL उत्पादन होता है

लक्ष्य एक इटरटेबल के किसी भी कार्यान्वयन में गुजरना है और उसी प्रकार का बैक आउट प्राप्त करना है। क्या यह संभव है?

+0

http://stackoverflow.com/questions/8235462/returning-original-collection-type-in-generic का डुप्लिकेट -method –

+2

@LuigiPlinge उस प्रश्न को 'CanBuildFrom' की आवश्यकता नहीं थी, क्योंकि' फ़िल्टर' की आवश्यकता नहीं है। यह प्रश्न बहुत समान है, और उस प्रश्न का _title_ निश्चित रूप से इसे कवर करता है, लेकिन इसे काम करने के लिए यहां थोड़ा और आवश्यक है। –

उत्तर

13

Iterable पर map विधि देता है एक Iterable, ताकि यदि TIterable का एक उपवर्ग है, यह map विधि Iterable वापस आ जाएगी है।

बेहतर टाइपिंग पाने के लिए आपको इसे इस तरह लिखने के लिए होगा:

import scala.collection.IterableLike 
def trimNonWordCharacters[T <: Iterable[String]](items: T with IterableLike[String, T]): T = 
    items map { _.replaceAll("\\W", "") } 

हालांकि, कि, या तो काम नहीं करेगा क्योंकि वहाँ कोई जानकारी T पर एक नक्शे एक और T उत्पन्न करने के लिए देते हैं। उदाहरण के लिए, BitSet को String में मैपिंग करने से BitSet का परिणाम नहीं हो सकता है। तो हमें कुछ और चाहिए: कुछ ऐसा जो सिखाता है कि T को T से कैसे बनाया जाए, जहां मैप किए गए तत्व String टाइप करें। इस तरह:

import scala.collection.IterableLike 
import scala.collection.generic.CanBuildFrom 
def trimNonWordCharacters[T <: Iterable[String]] 
         (items: T with IterableLike[String, T]) 
         (implicit cbf: CanBuildFrom[T, String, T]): T = 
    items map { _.replaceAll("\\W", "") } 
+0

आपको बहुत धन्यवाद- आपका स्पष्टीकरण बहुत जानकारीपूर्ण है और अब मुझे अंत में 'CanBuildFrom' (!) का उपयोग करने का एक तरीका पता है। –

0

@Daniel [एक जवाब के बजाय एक टिप्पणी क्योंकि टिप्पणी में कोड को ठीक से स्वरूपित नहीं है के रूप में प्रवेश], धन्यवाद विवरण के लिए, मैं भी इसे उपयोगी पाया। Iterable IterableLike से निकला है के रूप में, निम्नलिखित भी काम करने के लिए लगता है, और थोड़ा अधिक कॉम्पैक्ट है:

import scala.collection.IterableLike 
import scala.collection.generic.CanBuildFrom 
def trimNonWordCharacters[T <: IterableLike[String, T]] 
(items: T) 
(implicit cbf: CanBuildFrom[T, String, T]): T = 
items map { _.replaceAll("\\W", "") } 
संबंधित मुद्दे