2011-02-10 21 views
6

उदाहरण के लिए मैं erlang रिकॉर्ड है:Erlang रिकॉर्ड आइटम सूची

-record(state, {clients 
      }). 

मैं ग्राहकों क्षेत्र सूची से बना सकते हैं?

कि मैं सामान्य सूची में दर्ज क्लाइंट में रख सकता हूं? और मैं इस सूची में कुछ मूल्य कैसे जोड़ सकता हूं?

धन्यवाद।

उत्तर

7

शायद तुम जैसे कुछ मतलब है:

-module(reclist). 
-export([empty_state/0, some_state/0, 
     add_client/1, del_client/1, 
     get_clients/1]). 

-record(state, 
    {  
      clients = [] ::[pos_integer()], 
      dbname   ::char() 
    }).  

empty_state() -> 
    #state{}. 

some_state() -> 
    #state{ 
      clients = [1,2,3], 
      dbname = "QA"}. 

del_client(Client) -> 
    S = some_state(), 
    C = S#state.clients, 
    S#state{clients = lists:delete(Client, C)}. 

add_client(Client) -> 
    S = some_state(), 
    C = S#state.clients, 
    S#state{clients = [Client|C]}. 

get_clients(#state{clients = C, dbname = _D}) -> 
    C. 

टेस्ट:

1> reclist:empty_state(). 
{state,[],undefined} 
2> reclist:some_state(). 
{state,[1,2,3],"QA"} 
3> reclist:add_client(4). 
{state,[4,1,2,3],"QA"} 
4> reclist:del_client(2). 
{state,[1,3],"QA"} 

::[pos_integer()] मतलब यह है कि क्षेत्र के प्रकार के सकारात्मक पूर्णांक मानों की सूची, 1 से शुरू होता है; यह विश्लेषण उपकरण dialyzer के लिए संकेत है, जब यह टाइप चेकिंग करता है।

Erlang भी आप रिकॉर्ड पर पैटर्न मिलान का उपयोग की अनुमति देता है:

5> reclist:get_clients(reclist:some_state()). 
[1,2,3] 

अतिरिक्त पठन:


@JUST मेरा सही विकल्प answer मुझे याद दिलाता है कि मुझे प्यार है कि कैसे हास्केल डेटा प्रकार में फ़ील्ड के मान प्राप्त करने के बारे में जाता है।

data Car = Car {company :: String 
       ,model :: String 
       ,year :: Int 
       } deriving (Show) 

यह कार्यों company, model और year, डेटा प्रकार में है कि देखने क्षेत्रों बनाता है:

यहाँ एक डेटा प्रकार, Learn You a Haskell for Great Good! से चोरी, जो रिकॉर्ड वाक्य रचना का लाभ उठाता है की एक परिभाषा है। हम पहले एक नई कार बनाने:

ghci> Car "Toyota" "Supra" 2005 
Car {company = "Toyota", model = "Supra", year = 2005} 

या, रिकॉर्ड वाक्य रचना (खेतों के आदेश कोई फर्क नहीं पड़ता) का उपयोग:

ghci> Car {model = "Supra", year = 2005, company = "Toyota"} 
Car {company = "Toyota", model = "Supra", year = 2005} 
ghci> let supra = Car {model = "Supra", year = 2005, company = "Toyota"} 
ghci> year supra 
2005 

हम भी पैटर्न मिलान का उपयोग कर सकते हैं:

ghci> let (Car {company = c, model = m, year = y}) = supra 
ghci> "This " ++ C++ " " ++ m ++ " was made in " ++ show y 
"This Toyota Supra was made in 2005" 

मुझे याद है कि एरलांग में हास्केल के रिकॉर्ड सिंटैक्स के समान कुछ लागू करने का प्रयास किया गया था, लेकिन यह सुनिश्चित नहीं है कि वे सफल रहे हैं या नहीं।

कुछ पदों, इन प्रयासों के विषय में:

ऐसा नहीं है कि LFE मैक्रो, जो क्या योजना प्रदान करता है के समान हैं का उपयोग करता है (Racket, उदाहरण के लिए), जब आप कुछ संरचना का एक नया मान बनाने के लिए चाहते हैं लगता है:

> (define-struct car (company model year)) 
> (define supra (make-car "Toyota" "Supra" 2005)) 
> (car-model supra) 
"Supra" 

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

+0

ewps, यह 'डायलज़र' है। Erlang [रिकॉर्ड्स] पर अधिक (http://www.erlang.org/doc/programming_examples/records.html)। –

+0

ओह, यह 'क्लाइंट = [] :: [pos_integer()], ' –

+0

होना चाहिए था, क्या आप अपने 2600 क्रेडिट पॉइंट्स के साथ अपडेट करने के लिए अपनी पोस्ट संपादित नहीं कर सकते? – ndim

1

यदि आप केवल राज्य में ग्राहकों की सूची से एकल आइटम जोड़ रहे हैं या निकाल रहे हैं तो आप मैक्रो के साथ टाइपिंग पर कटौती कर सकते हैं।

-record(state, {clients = [] }). 

-define(AddClientToState(Client,State), 
    State#state{clients = lists:append([Client], State#state.clients) }). 

-define(RemoveClientFromState(Client,State), 
    State#state{clients = lists:delete(Client, State#state.clients) }). 

यहाँ एक परीक्षण escript कि यह दर्शाता है है:

#!/usr/bin/env escript 

-record(state, {clients = [] }). 

-define(AddClientToState(Client,State), 
    State#state{clients = lists:append([Client], State#state.clients)} ). 

-define(RemoveClientFromState(Client,State), 
    State#state{clients = lists:delete(Client, State#state.clients)} ). 


main(_) -> 

    %Start with a state with a empty list of clients. 
    State0 = #state{}, 
    io:format("Empty State: ~p~n",[State0]), 

    %Add foo to the list 
    State1 = ?AddClientToState(foo,State0), 
    io:format("State after adding foo: ~p~n",[State1]), 

    %Add bar to the list. 
    State2 = ?AddClientToState(bar,State1), 
    io:format("State after adding bar: ~p~n",[State2]), 

    %Add baz to the list. 
    State3 = ?AddClientToState(baz,State2), 
    io:format("State after adding baz: ~p~n",[State3]), 

    %Remove bar from the list. 
    State4 = ?RemoveClientFromState(bar,State3), 
    io:format("State after removing bar: ~p~n",[State4]). 

परिणाम:

Empty State: {state,[]} 
State after adding foo: {state,[foo]} 
State after adding bar: {state,[bar,foo]} 
State after adding baz: {state,[baz,bar,foo]} 
State after removing bar: {state,[baz,foo]} 
+1

इस तरह के मामलों में मैं मैक्रो के बजाए फ़ंक्शन का उपयोग करना पसंद करता हूं। कोड को अनुवर्ती, रिफैक्टर और परीक्षण करने में आसान बनाता है। –

3

Yasir's answer सही एक है, लेकिन मैं आपको दिखाने के लिए क्यों यह काम करता है जिस तरह से जा रहा हूँ यह काम करता है ताकि आप रिकॉर्ड को थोड़ा बेहतर समझ सकें।

एरलांग में रिकॉर्ड्स एक हैक (और एक सुंदर बदसूरत एक) हैं।

{state, [], undefined} 

: यासिर के जवाब से रिकॉर्ड परिभाषा ...

-record(state, 
    {  
      clients = [] ::[pos_integer()], 
      dbname   ::char() 
    }). 

... जब आप #state{} के साथ इस दृष्टांत (यासिर empty_state/0 समारोह में किया था के रूप में) का उपयोग करना, क्या तुम सच में वापस पाने के लिए इस है यही कहना है कि आपका "रिकॉर्ड" रिकार्ड के नाम से रिकॉर्ड किया गया है (इस मामले में state) रिकॉर्ड के बाद। बीईएएम के अंदर कोई रिकॉर्ड नहीं है। यह केवल एक और tuple है जिसमें Erlang डेटा प्रकार इसके भीतर निहित है। यह समझने की कुंजी है कि चीजें कैसे काम करती हैं (और रिकॉर्ड की सीमाएं बूट करने के लिए)।

अब जब यासिर ऐसा किया ...

add_client(Client) -> 
    S = some_state(), 
    C = S#state.clients, 
    S#state{clients = [Client|C]}. 

... S#state.clients बिट कोड आंतरिक कि element(2,S) तरह लग रहा है में तब्दील हो। आप दूसरे शब्दों में, मानक ट्यूपल मैनिपुलेशन फ़ंक्शंस का उपयोग कर रहे हैं। S#state.clients एक ही बात कहने का सिर्फ एक प्रतीकात्मक तरीका है, लेकिन इस तरह से आपको यह पता चलता है कि वास्तव में कौन सा तत्व 2 वास्तव में है। यह वाक्य रचनात्मक saccharine है कि एक त्रुटि प्रवण तरीके से अपने tuples में व्यक्तिगत क्षेत्रों का ट्रैक रखने में सुधार है।

अब उस अंतिम S#state{clients = [Client|C]} बिट के लिए, मैं बिल्कुल सकारात्मक नहीं हूं कि दृश्यों के पीछे कौन सा कोड उत्पन्न होता है, लेकिन यह संभवतः केवल सीधी चीजें हैं जो {state, [Client|C], element(3,S)} के बराबर होती हैं। यह:

  • (#state रूप में प्रदान की) रिकॉर्ड के नाम के साथ एक नया टपल,
  • प्रतियां S से तत्वों (S# भाग से तय),
  • clients टुकड़ा द्वारा ओवरराइड के अलावा
  • टैग कर देता है {clients = [Client|C]}

यह सब जादू दृश्यों के पीछे प्रीप्रोकैसिंग हैक के माध्यम से किया जाता है।

यह समझना कि दृश्यों के पीछे रिकॉर्ड कैसे काम करते हैं, रिकॉर्ड के साथ लिखे गए कोड को समझने के साथ-साथ उन्हें स्वयं का उपयोग करने के तरीके के बारे में समझने के लिए फायदेमंद है (समझने के लिए नहीं कि चीजें जो "समझ में आती हैं" रिकॉर्ड के साथ काम नहीं करती हैं - क्योंकि वे वास्तव में सार मशीन में मौजूद नहीं हैं ... अभी तक)।