Tiene una matriz estática de char
. Desea pasarlo a una función que toma immutable(char)[]
. La forma solo de hacer eso sin ninguna asignación es emitir. Piénsalo. Lo que quieres es un tipo para actuar como si fuera otro. Eso es lo que hace el casting. Puedes elegir usar assumeUnique
para hacerlo, ya que eso hace exactamente el elenco que estás buscando, pero si eso realmente te gana algo es discutible. Su objetivo principal es documentar que lo que está haciendo el elenco es hacer que el valor que se está emitiendo se trate como immutable
y que no haya otras referencias a él. En cuanto a su ejemplo, eso es esencialmente cierto, ya que es lo último en la función, pero si usted quiere hacer eso en general depende de usted.Dado que es una matriz estática que arriesga los problemas de memoria si la arruinas y la pasas a una función que permite hacer una fuga, no estoy seguro de que assumeUnique
sea la mejor opción. Pero, de nuevo, depende de usted.
Independientemente de si está haciendo un cast (explícitamente o con assumeUnique
), necesita estar seguro de que la función a la que lo está transfiriendo no va a filtrar las referencias a los datos que está pasando a él. Si lo hace, entonces estás pidiendo problemas.
La otra solución, por supuesto, es cambiar la función para que tome const(char)[]
, pero eso aún corre el riesgo de perder referencias a los datos que está pasando. Por lo tanto, aún necesita estar seguro de qué función realmente va a hacer la función. Si es pure
, no devuelve const(char)[]
(o cualquier cosa que pueda contener const(char)[]
), y no hay forma de que pueda filtrarse a través de cualquiera de los otros argumentos de la función, entonces está seguro, pero si alguno de ellos no es cierto , entonces vas a tener que tener cuidado. Por lo tanto, en última instancia, creo que todo lo que realmente usa para usar const(char)[]
en lugar de convertirlo en string
es que no tiene que emitir. Eso es aún mejor, ya que evita el riesgo de arruinar el elenco (y es mejor, en general, evitar el casting cuando puedes), pero aún tienes las mismas cosas de las que preocuparte cuando se trata de escapar de las referencias.
Por supuesto, eso también requiere que usted pueda cambiar la función para que tenga la firma que desea. Si no puedes hacer eso, entonces vas a tener que lanzar. Creo que en este punto, más de las funciones de Phobos basadas en cadenas han sido modificadas para que sean plantillas en el tipo de cadena. Por lo tanto, esto debería ser menos problemático ahora con Fobos de lo que solía ser. Algunas funciones (en particular las de archivo std.) aún necesitan plantillas, pero, en última instancia, las funciones en Phobos que requieren string
específicamente deberían ser bastante raras y tendrán un buen motivo para requerirlas.
En última instancia, sin embargo, el problema es que está tratando de tratar una matriz estática como si fuera una matriz dinámica, y mientras que D definitivamente le permite hacer eso, está asumiendo un riesgo definitivo al hacerlo, y debe asegurarse de que las funciones que está utilizando no pierdan ninguna referencia a los datos locales que les está pasando.
¡Herejía, herejía! Use 'snprintf'! : D – BCS
Creo que el # 3 es realmente la solución correcta. string -> inmutable (char) [] significa que los datos no pueden cambiar (siempre que sigan siendo referenciados en alguna parte, de lo contrario, el GC puede recogerlo, AFAIK). No creo que puedas hacer una garantía así para los datos asignados por la pila. Pero a menos que renderText realmente necesite almacenar texto en alguna parte, debería usar const (char) []. Como inmutable es más fuerte que const, solo se debe usar cuando sea necesario. Estoy de acuerdo, sin embargo, que muchas funciones en phobos innecesariamente toman cadenas en lugar de const (char) [], que deberían ser arregladas en phobos. – jpf
@jpf: Estoy de acuerdo 100%. –