2012-11-02 8 views
10

के साथ केस क्लास की प्रतिलिपि बनाना मैं स्कैला के लिए बिल्कुल नया हूं और मेरे पास लक्षणों से आने वाले डेटा को संरक्षित करते समय केस क्लास की प्रतिलिपि बनाने का सबसे अच्छा तरीका है। उदाहरण के लिए, मान लीजिए कि मैं जाने के बाद:स्कैला:

trait Auditing { 

    var createTime: Timestamp = new Timestamp(System.currentTimeMillis) 
} 

case class User(val userName: String, val email: String) extends Auditing 

val user = User("Joe", "[email protected]") 

तो मैं एक पैरामीटर के साथ एक नई प्रतिलिपि बदल बनाना चाहते:

val user2 = user.copy(email = "[email protected]") 

अब, ऊपर के उदाहरण में, संपत्ति createTime नहीं मिलता है कॉपी किया गया क्योंकि यह उपयोगकर्ता केस क्लास के निर्माता में परिभाषित नहीं है। तो मेरा सवाल यह है कि यह मानते हुए कि कन्स्ट्रक्टर में createTime को ले जाना एक विकल्प नहीं है, उपयोगकर्ता ऑब्जेक्ट की एक प्रति प्राप्त करने का सबसे अच्छा तरीका क्या है जिसमें विशेषता से मूल्य शामिल है?

मैं स्काला 2.9.1

उपयोग कर रहा हूँ पहले से

धन्यवाद! जो

+0

काफी विकल्प आप से आगे नहीं है: या तो आप मैन्युअल रूप से इस तरह के एक विधि है कि 'User' मामले वर्ग की घोषणा में प्रतिलिपि आप चाहते हैं का उत्पादन करेगा लागू करने या आप स्काला का उपयोग 2.10 मैक्रोज़ स्वचालित करने के लिए शामिल हैं। दूसरा विकल्प निश्चित रूप से शुरुआत के लिए एक आसान काम नहीं होगा। –

+1

@NikitaVolkov यदि आप मुझे मैक्रोज़ के साथ ऐसा करने के उदाहरण के साथ मुझे/हमें प्रदान करने के लिए तैयार थे, तो यह बहुत अच्छा होगा। –

+2

@ एमएचएस मैं क्लब में शामिल हूं। मै मैक्रोज़ में एक नौसिखिया हूं, इसलिए मैंने इसे उत्तर के रूप में पोस्ट नहीं किया है। लेकिन [यहां कैसे है] (http://stackoverflow.com/a/10397595/485115) मैंने 'टूलबॉक्स' एपीआई के साथ एक बहुत ही समान कार्य हल किया। स्वीकार्य उत्तर मैक्रोज़ पर आधारित है, लेकिन मुझे लगता है कि यह नवीनतम स्कैला संस्करण का समर्थन नहीं करता है। –

उत्तर

6

आप उस व्यवहार के साथ कॉपी विधि को ओवरराइड कर सकते हैं।

case class User(val userName: String, val email: String) extends Auditing 
{ 
    def copy(userName = this.userName, email = this.email) { 
    val copiedUser = User(userName, email) 
    copiedUser.createTime = createTime 
    copiedUser  
    } 
} 
3

जब मैं रूबेन के अलावा कोई अन्य समाधान देखते हैं, मैं आवश्यकता निर्माता आर्ग अछूता छोड़ने के लिए समझ में नहीं आता।

case class User(userName: String, email: String, 
    override val createTime:Timestamp = new Timestamp(System.currentTimeMillis)) 
     extends Auditing 

आप उपयोगकर्ता createTime अधिलेखित करने के लिए सक्षम होने के लिए नहीं करना चाहते हैं, तो आप अभी भी उपयोग कर सकते हैं:: यह सबसे प्राकृतिक समाधान होगा

case class User private (userName: String, email: String, 
    override val createTime:Timestamp) extends Auditing { 
    def this(userName: String, email: String) = 
    this(userName, email, new Timestamp(System.currentTimeMillis)) 
} 

केवल दोष यह है कि आप की जरूरत है new User("Joe", "[email protected]") लिखें, क्योंकि प्राथमिक कन्स्ट्रक्टर अब निजी है।

0

आप केस क्लास का उपयोग न करने के बेहतर हो सकते हैं। आप कार्यक्षमता को आसानी से कार्यान्वित कर सकते हैं जिसकी आपको आवश्यकता है। नीचे दिया गया कोड उस प्रतिलिपि विधि को लागू करता है जो आप चाहते थे, बिना किसी कन्स्ट्रक्टर, मूल कन्स्ट्रक्टर को छुपाता है, और एक एक्स्ट्रेक्टर बनाता है ताकि आप कथन के मामले में उपयोगकर्ता का उपयोग कर सकें।

class User private(val userName: String, 
        val email: String, 
        val timeStamp: Timestamp = 
        new Timestamp(System.currentTimeMillis)) { 

    def copy(uName: String = userName, 
      eMail: String = email) = 
    new User(uName, eMail, timeStamp) 
} 

object User { 
    def apply(userName: String, email: String) = 
    new User(userName, email) 

    def unapply(u: User) = Some((u.userName, u.email, u.timeStamp)) 
}