Переписать переменную в Erlang

erlang

187 просмотра

3 ответа

Я играю с записями и списком. Пожалуйста, я хочу знать, как использовать одну переменную дважды. Когда я назначаю какие-либо значения в переменную _list и после этого я пытаюсь переписать эту переменную, тогда возникает ошибка:

** ошибка исключения: нет совпадения правого значения

-module(hello).
-author("anx00040").

-record(car, {evc, type, color}).
-record(person, {name, phone, addresa, rc}).
-record(driver, {rc, evc}).

-record(list, {cars = [], persons = [], drivers = []} ).

%% API
-export([helloIF/1, helloCase/1, helloResult/1, helloList/0, map/2, filter/2, helloListCaA/0, createCar/3, createPerson/4, createDriver/2, helloRecords/0, empty_list/0, any_data/0, del_Person/1, get_persons/1, do_it_hard/0, add_person/2]).


createCar(P_evc, P_type, P_color) -> _car = #car{evc = P_evc, type = P_type, color = P_color}, _car
  .
createPerson(P_name, P_phone, P_addres, P_rc) -> _person= #person{name = P_name, phone = P_phone, addresa = P_addres, rc = P_rc}, _person
  .
createDriver(P_evc, P_rc) -> _driver = #driver{rc = P_rc, evc = P_evc}, _driver
  .  

empty_list() ->
  #list{}.

any_data() ->
  _car1 = hello:createCar("BL 4", "Skoda octavia", "White"),
  _person1 = hello:createPerson("Eduard B.","+421 917 111 711","Kr, 81107 Bratislava1", "8811235"),
  _driver1 = hello:createDriver(_car1#car.evc, _person1#person.rc),

  _car2 = hello:createCar("BL 111 HK", "BMW M1", "Red"),
  _person2 = hello:createPerson("Lenka M","+421 917 111 111","Krizn0, 81107 Bratislava1", "8811167695"),
  _driver2 = hello:createDriver(_car2#car.evc, _person2#person.rc),

  _car3 = hello:createCar("BL 123 AB", "Audi A1 S", "Black"),
  _person3 = hello:createPerson("Stela Ba.","+421 918 111 711","Azna 20, 81107 Bratislava1", "8811167695"),
  _driver3 = hello:createDriver(_car3#car.evc, _person3#person.rc),

  _list = #list{
    cars = [_car1,_car2,_car3],
    persons = [_person1, _person2, _person3],
    drivers = [_driver1, _driver2, _driver3]},
  _list.


add_person(List, Person) ->
  List#list{persons = lists:append([Person], List#list.persons) }.

get_persons(#list{persons = P}) -> P.

do_it_hard()->
  empty_list(),
  _list = add_person(any_data(), #person{name = "Test",phone = "+421Test", addresa = "Testova 20 81101 Testovo", rc =88113545}),
  io:fwrite("\n"),
  get_persons(add_person(_list, #person{name = "Test2",phone = "+421Test2", addresa = "Testova 20 81101 Testovo2", rc =991135455}))
.

Но это вызывает ошибку, когда я дважды использую переменную _list:

do_it_hard()->
  empty_list(),
  _list = add_person(any_data(), #person{name = "Test",phone = "+421Test", addresa = "Testova 20 81101 Testovo", rc =88113545}),
  _list =add_person(_list, #person{name = "Test2",phone = "+421Test2", addresa = "Testova 20 81101 Testovo2", rc =991135455}),
  get_persons(_list)
.
Автор: Eddy_Screamer Источник Размещён: 12.11.2019 09:53

Ответы (3)


2 плюса

Решение

Я использовал Google ...

Erlang - это язык с одним заданием. То есть, если переменной присвоено значение, ей нельзя присвоить другое значение. В этом смысле он похож на алгебру, а не на большинство традиционных языков программирования.

http://www.cis.upenn.edu/~matuszek/General/ConciseGuides/concise-erlang.html

Автор: Eddy_Screamer Размещён: 11.01.2015 01:14

2 плюса

В REPL может быть удобно экспериментировать с вещами, повторно используя имена переменных. Там вы можете сделать так, f(A).чтобы Эрланг «забыл» текущее назначение A.

1> Result = connect("goooogle.com").
{error, "server not found"}
2> % oops! I misspelled the server name
2> f(Result).
ok
3> Result = connect("google.com").
{ok, <<"contents of the page">>}

Обратите внимание, что это только удобная функция REPL. Вы не можете сделать это в реальном коде.

В реальном коде переменные могут быть назначены только один раз. В процедурном языке (C, Java, Python и т. Д.) Типичный вариант переназначения - циклы:

for (int i = 0; i < max; i++) {
  conn = connect(servers[i]);
  reply = send_data(conn);
  print(reply);
}

В приведенном выше описании переменных i, connи replyПереоформлен в каждой итерации цикла.

Функциональные языки используют рекурсию для выполнения своих циклов:

send_all(Max, Servers) ->
 send_loop(1, Max, Servers).

send_loop(Current, Max, _Servers) when Current =:= Max->
 ok;
send_loop(Current, Max, Servers) ->
 Conn = connect(lists:nth(Current, Servers)),
 Reply = send_data(Conn),
 print(Reply).

Это не очень идиоматичный Эрланг; Я пытаюсь сделать так, чтобы это отражало процедурный код выше.

Как видите, я получаю тот же эффект, но мои назначения внутри функции фиксированы.

Как примечание, вы используете много имен переменных, начинающихся с подчеркивания. В Erlang это способ намека на то, что вы не будете использовать значение этих переменных. (Как и в приведенном выше примере, когда я достиг конца моего списка, меня не волнует список серверов.) Использование подчеркивания в начале, так как в вашем коде отключаются некоторые полезные предупреждения компилятора и могут смутить других разработчиков кто смотрит на твой код

Автор: Nathaniel Waisbrot Размещён: 12.01.2015 04:08

2 плюса

В некоторых ситуациях удобно использовать SeqBind :

SeqBind - это преобразование синтаксического анализа, которое автоматически нумерует все вхождения этих привязок после суффикса @ (создание L @ 0, L @ 1, Req @ 0, Req @ 1) и так далее.

Простой пример:

...
-compile({parse_transform,seqbind}).
...

List@ = lists:seq(0, 100),
List@ = lists:filter(fun (X) -> X rem 2 == 0 end, List@)
...
Автор: P_A Размещён: 13.01.2015 09:13
Вопросы из категории :
32x32