Строка-приложение не работает; продолжает переписывать предыдущие строки - PullRequest
4 голосов
/ 21 ноября 2011

Я пытаюсь выполнить простую задачу - добавить число в строку несколько раз и надеюсь, что это создаст строку.

Но это не работает, каждый вызов (string-append ....), кажется,вообще ничего не делать.

Вот мой код:

(define myString "")
(string-append (number->string 4) myString)
(string-append (number->string 5) myString)
(string-append (number->string 6) myString)
(string-append (number->string 7) myString)
(display myString)

это отображает:

"4"

"5"

"6"

"7"

и пустая строка для (display myString)

Что я делаю не так?

также, если я делаю этоЭто как-то иначе, поэтому он тоже не работает:

(define myString "")
(string-append myString (number->string 4))
(string-append myString (number->string 5))
(string-append myString (number->string 6))
(string-append myString (number->string 7))
(display myString)

Спасибо за любую помощь

Ответы [ 2 ]

8 голосов
/ 21 ноября 2011

Выражение (string-append (number->string 4) myString) оценивается как "4", поэтому ваш код печатает 4.Аналогично, (string-append (number->string 5) myString) оценивается как "5" и так далее.Ни один из них на самом деле не изменяет значение переменной myString.

Чтобы фактически изменить значение переменной, вам нужно присвоить этой переменной с использованием языковой формы Схемы для назначения,set!.(! в названии является соглашением Схемы, говорящим вам, что это разрушительная операция, то есть та, которая уничтожает предыдущее значение в myString и заменяет его новым.Например, вы могли бы написать:

(define myString "")
(set! myString (string-append myString (number->string 4))) ;; assigns "4" to myString
(set! myString (string-append myString (number->string 5))) ;; assigns "45" to myString
(set! myString (string-append myString (number->string 6))) ;; assigns "456" to myString
(set! myString (string-append myString (number->string 7))) ;; assigns "4567" to myString
(display myString) ;; prints 4567

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

(define myString 
  (string-append (number->string 4) 
    (string-append (number->string 5) 
      (string-append (number->string 6) 
        (string-append (number->string 7) "")))))
(display myString) ;; prints 4567

И в этот момент вместо написания такого повторяющегося кода я бы сделал fold-right:

(define myString 
  (fold-right (lambda (num str) 
                (string-append (number->string num) str)) 
    "" (list 4 5 6 7)))
(display myString) ;; prints 4567

Если вам нужно присвоить "4567" глобальной переменной с именем myStringзатем вы можете просто заменить define на set! в любом из двух приведенных выше фрагментов кода.Однако, хотя set! иногда может пригодиться, идиоматическая схема имеет тенденцию использовать set! s и другие деструктивные операции экономно.Мне нравится рассматривать восклицательный знак как означающий «Действуй с осторожностью!»

7 голосов
/ 21 ноября 2011

string-append не изменяет существующую строку;он возвращает новую строку, которая является результатом операции.

Если это кажется необычным, рассмотрим оператор сложения +.Когда я пишу

3+4

, я не изменяю 3 на 7, просто возвращаю результат операции.

Итак, в вашем случае, если вы напишите

(define my-string (string-append (number->string 4) (number->string 5)))
(display my-string)

Вы должны увидеть

45

Чтобы проконсультировать вас дальше, это может помочь узнать, куда вы направляетесь.

...