usar try retornar net manejo excepciones errores error control como catch capturar asp error-handling rust optional idiomatic rust-result

error-handling - try - manejo de excepciones en asp net c#



¿Cuál es la forma idiomática de devolver un error de una función sin resultado si es exitosa? (2)

En Rust, creo que la forma idiomática de lidiar con los errores recuperables es usar Result. Por ejemplo, esta función es claramente idiomática:

fn do_work() -> Result<u64, WorkError> {...}

Por supuesto, también hay funciones que tienen un estado de falla único y obvio, y por lo tanto usan el tipo de Opción en su lugar. Un ejemplo idiomático sería este:

fn do_work() -> Option<u64>

Todo esto se aborda directamente en la documentación. Sin embargo, estoy confundido sobre el caso en el que una función puede fallar, pero no tiene un valor significativo cuando tiene éxito. Compara las siguientes dos funciones:

fn do_work() -> Option<WorkError> // vs fn do_work() -> Result<(), WorkError>

Simplemente no estoy seguro de cuál de estos es más idiomático, o se usa más a menudo en el código Rust del mundo real. Mi recurso de consulta para preguntas como esta es el libro Rust, pero no creo que esto se aborde en su sección " Manejo de errores ". Tampoco he tenido mucha suerte con ninguna otra documentación de Rust.

Por supuesto, esto parece bastante subjetivo, pero estoy buscando fuentes autorizadas que indiquen qué forma es idiomática, o por qué una forma es superior (o inferior) a la otra. (También tengo curiosidad por saber cómo se compara la convención con otros idiomas que utilizan en gran medida los "errores como valores", como Go y Haskell).


Rust está "muy fuertemente tipado" (y, por favor, no me diga cómo mido qué tan bien tipeado es un idioma ...). Me refiero a esto en el sentido de que Rust generalmente le brinda las herramientas para permitir que los tipos "hablen" por usted y documenten su código, por lo que es idiomático usar esta función para escribir código legible.

En otras palabras, la pregunta que está haciendo debe ser más "¿qué tipo representa mejor lo que la función hace a cualquiera que lea su firma?"

Para el Result<(), Workerror> puede verlo directamente desde los documentos

El resultado es un tipo que representa el éxito (Ok) o el fracaso (Err)

Por lo tanto, especializado para su caso, significa que su función no devuelve nada si es exitosa (representada por Ok<()> ) o WorkError si hay un error ( Err<WorkError> ). Esta es una representación muy directa en el código de la forma en que describió la función en su pregunta.

Compare esto con la Option<WorkError> u Option<()>

La opción Tipo representa un valor opcional: todas las Opciones son Algunas y contienen un valor o Ninguna, y no

En su caso, la Option<WorkError> diría al lector "esta función debería devolver un WorkError pero puede no devolver nada". Puede documentar que el caso de "no devolver nada" significa que la función fue realmente exitosa, pero eso no es muy evidente solo por los tipos.

Option<()> dice "esta función no puede devolver nada o no tiene un retorno significativo", lo que puede ser razonable decir si WorkError no contiene otra información (como un tipo de error o un mensaje de error) y es prácticamente solo una forma de diga "ha ocurrido un error". En este caso, un bool simple lleva la misma información ... De lo contrario, el Result permite devolver más información asociada con el error.


Utilice fn do_work() -> Result<(), WorkError> .

Result<(), WorkError> significa que desea que se realice el trabajo, pero puede fallar.

Option<WorkError> significa que desea obtener un error, pero puede estar ausente.

Es probable que desee que se realice el trabajo pero que no se do_work() un error al escribir do_work() , por lo que Result<(), WorkError> es la mejor opción.

Espero que la Option<WorkError> solo se use en casos como fn get_last_work_error() -> Option<WorkError> .