Записи были добавлены в язык Erlang, поскольку работа с полями кортежей по номерам была подвержена ошибкам, особенно когда код изменялся во время разработки, а поля кортежей добавлялись, изменялись или удалялись. Не используйте числа для идентификации полей записи и не обрабатывайте записи, используя их базовое представление кортежа, так как оба работают против назначения записей и не нужны.
В вашем коде, а не с использованием номеров полей записис lists:keyfind/3
используйте сами имена записей. Я изменил вашу функцию get_ship/2
, чтобы сделать это:
get_ship(Shipping_State, Ship_ID) ->
#ship{id=ID, name=Name, container_cap=ContainerCap} = lists:keyfind(Ship_ID, #ship.id, Shipping_State#shipping_state.ships),
io:format("id = ~w, name = ~s, container cap = ~w~n",[ID, Name, ContainerCap]).
Синтаксис #<record_name>.<record_field_name>
предоставляет основной номер поля записи. В приведенном выше вызове lists:keyfind/3
#ship.id
предоставляет номер поля для поля id
записи ship
. Это продолжит работать правильно, даже если вы добавите поля в запись, и в отличие от необработанного числа, это вызовет ошибку компиляции, если вы решите удалить это поле из записи в какой-то момент.
Если вы загрузитеОпределения записей в вашей оболочке с помощью команды rr
, вы можете видеть, что #ship.id
возвращает ожидаемый номер поля:
1> rr("shipping.hrl").
[container,port,ship,shipping_state]
2> #ship.id.
2
С дополнительными исправлениями, приведенными выше для правильной обработки возвращенной записи, онатеперь работает как положено, как показывает этот сеанс оболочки:
3> {ok, ShippingState} = shipping:init().
{ok,{shipping_state,[{ship,1,"Santa Maria",20},
{ship,2,"Nina",20},
{ship,3,"Pinta",20},
{ship,4,"SS Minnow",20},
{ship,5,"Sir Leaks-A-Lot",20}],
[{container,1,200},
...
4> shipping:get_ship(ShippingState, 1).
id = 1, name = Santa Maria, container cap = 20
ok