을 내가 얼랑 기록이 있습니다얼랑 기록 항목 목록 예를 들어
-record(state, {clients
}).
내가 클라이언트 필드 목록에서 만들 수 있습니까?
정상적인 목록으로 제출 한 클라이언트에 보관할 수 있습니까? 그리고이 목록에 몇 가지 값을 어떻게 추가 할 수 있습니까?
감사합니다.
을 내가 얼랑 기록이 있습니다얼랑 기록 항목 목록 예를 들어
-record(state, {clients
}).
내가 클라이언트 필드 목록에서 만들 수 있습니까?
정상적인 목록으로 제출 한 클라이언트에 보관할 수 있습니까? 그리고이 목록에 몇 가지 값을 어떻게 추가 할 수 있습니까?
감사합니다.
어쩌면 당신은 같은 의미 :
-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
에 대한 힌트입니다.
얼랑 또한 기록에 패턴 매칭 사용 할 수 있습니다 :
5> reclist:get_clients(reclist:some_state()).
[1,2,3]
추가 읽기 :
을@JUST MY 올바른 OPINION의 answer은 하스켈이 데이터 유형의 필드 값을 얻는 방법을 좋아한다는 것을 기억하게했습니다. 그것은 기능 company
, model
및 year
, 데이터 타입에 해당 조회 필드를 생성
data Car = Car {company :: String
,model :: String
,year :: Int
} deriving (Show)
:
여기 레코드 구문을 활용 Learn You a Haskell for Great Good! 도난 데이터 형식의 정의이다.
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"
: 우리는 심지어 패턴 매칭을 사용할 수 있습니다
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> Car "Toyota" "Supra" 2005
Car {company = "Toyota", model = "Supra", year = 2005}
또는 : 우리는 먼저 새 차를 만들
Erlang에서 Haskell의 레코드 구문과 비슷한 것을 구현하려고 시도했지만 기억이 잘 안 나는지를 기억합니다. 이러한 시도와 관련된
일부 게시물 :
LFE는 당신이 어떤 구조의 새 값을 생성 할 때 (예를 들어, Racket) 방식을 제공하는 기능과 유사 매크로를 사용하는 것 같다
> (define-struct car (company model year))
> (define supra (make-car "Toyota" "Supra" 2005))
> (car-model supra)
"Supra"
나는 우리가 '희망을 미래에 Haskell 레코드 구문에 가까운 것이 있다면, 실제로 유용하고 편리 할 것입니다.
상태의 클라이언트 목록에서 단일 항목 만 추가하거나 제거하는 경우 매크로를 사용하여 타이핑하는 것을 줄일 수 있습니다. 여기
-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]}
이런 종류의 경우 매크로 대신 함수를 사용하는 것을 선호합니다. 코드를 따르기 쉽고, 리팩터링하고 테스트합니다. –
Yasir's answer 올바른 일이지만, 나는 그것이 방식으로 작동하는 이유를 보여 드리겠습니다 그것은 당신이 조금 더 나은 기록을 이해할 수 있도록 작동합니다.
얼랑 (Erlang)의 기록은 해킹 (그리고 꽤 추한 것)입니다.
{state, [], undefined}
: 당신이 (시르가 empty_state/0
기능에서와 마찬가지로) #state{}
으로이 인스턴스를 야시의 대답에서 레코드 정의 ...
-record(state,
{
clients = [] ::[pos_integer()],
dbname ::char()
}).
를 ... 사용하여, 당신이 정말 돌아 가야하는 것은 이것이다 즉, "레코드"는 레코드 이름 (이 경우 state
)과 함께 레코드 집합의 태그가 붙은 튜플입니다. 빔 내부에 레코드가 없습니다. 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가
인지 알 수있는 방식으로입니다. 이것은 문법상의 사카린으로, 튜플의 개별 필드를 오류가 발생하기 쉬운 방식으로 추적하는 것보다 개선 된 기능입니다.
이제 마지막 코드 인 S#state{clients = [Client|C]}
비트에 대해 배후에서 어떤 코드가 생성되는지는 확실하지 않지만, {state, [Client|C], element(3,S)}
과 같은 간단한 코드 일 가능성이 높습니다. 그것은 :
#state
제공) 레코드의 이름으로 새로운 튜플S#
부에 의해 결정) S
의 요소에 의해 재정의 clients
편 제외{clients = [Client|C]}
.이 마법은 모두 무대 뒤에서 전처리 해킹을 통해 이루어집니다.
레코드가 장면 뒤에서 어떻게 작동하는지 이해하면 레코드를 사용하여 작성된 코드를 이해하고이를 사용하는 방법을 이해하는 데 모두 도움이됩니다. ("이해가가는 것"이 레코드와 함께 작동하지 않는 이유를 이해하는 것은 물론 말할 필요도 없음) 왜냐하면 그것들은 추상 기계에 실제로 존재하지 않기 때문입니다.
ewps, '투석기'입니다. Erlang [Records]에 대한 자세한 정보 (http://www.erlang.org/doc/programming_examples/records.html). –
아, 그것은'clients = [] :: [pos_integer()], –
이어야합니다. 2600 크레딧 포인트로 업데이트하기 위해 자신의 포스트를 편집 할 수 없습니까? – ndim