lisp común: convierte un número en una cadena: escribir en cadena vs prin1-to-string vs princ-to-string

CorePress2024-01-25  9

Supongamos que tengo un número en Common Lisp y quiero convertirlo en una cadena. Hay al menos tres funciones que pueden convertir un número en una cadena: escribir en cadena, prin1-to-string y princ-to-string.

Hasta donde yo sé, las tres funciones dan el mismo resultado cuando se usan con números. ¿Es realmente así? ¿Hay algún caso extremo que deba tener en cuenta? ¿Cuál debo usar?



------------------------------------

No debería haber diferencia, pero WRITE-TO-STRING tiene argumentos de palabras clave. Para efectos similares con las otras dos funciones, sería necesario vincular una variable de impresora alrededor de la llamada.

CL-USER 1 > (write-to-string 12 :base 16)
"C"

CL-USER 2 > (let ((*print-base* 16))
              (prin1-to-string 12))
"C"

FORMATambién puedo crear cadenas:

CL-USER 3 > (format nil "~16R" 12)
"C"

CL-USER 4 > (format nil "~vR" 16 12)
"C"



------------------------------------

Creo que vale la pena señalar que debes tener mucho cuidado con los monstruos babeantes que acechan en las esquinas cuando utilizas cualquiera o todos los métodos write-to-string, prin1-to-string y princ-to-string.

Como ejemplo, considere esto:

> (dotimes (i 20)
    (print i))

0 
1 
2 
3 
4 
5 
six 
seven 
eight 
IX 
X 
XI 
XII 
XIII 
XII 
XIII 
XIII 
XIII 
XII 
XII 
nil

Este es un resultado completamente legal y cualquier implementación conforme lo produciría (o de hecho, algo similar, ya que había algunos números aleatorios involucrados).

La forma de conseguir esto es estableciendo *print-pretty* en verdadero y luego haciendo un par de cosas entretenidas con el pprin.t tabla de despacho.

Este puede ser el monstruo más grande que acecha, pero hay otros menores: *print-base* *print-radix* entre ellos.

Como mínimo, debes rodear las llamadas a estas funciones con (with-standard-io-syntax...) si quieres estar seguro de que el resultado que obtienes es el que esperas.

Usar formato (como en (format nil "~D" n)) es más seguro (ya no necesita preocuparse por cosas como *print-base* y *print-radix*) pero aún es vulnerable al valor ambiental de *print-pretty* y, por lo tanto, a los juegos anteriores con la tabla de despacho de pprint. Creo (pero no estoy del todo seguro) que

(let ((*print-pretty* nil))
  (format nil "~D" 13))

debería devolver la cadena "13"

CompartirSeguir Respondido

30 de marzo de 2021 a las 21:12

usuario5920214

usuario5920214

2

¿Cómo obtuviste exactamente ese resultado para (dotimes (i 20) (print i))?

- Flujo

19 de abril de 2021 a las 11:56

@Flux: Ahora no recuerdo los detalles, pero sí el (ab)uso de la bonita interfaz de la impresora. La bonita impresora de CL es... bastante flexible.

usuario5920214

19 de abril de 2021 a las 12:24

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare