Попробуйте / поймайте исключения на красном языке

У меня есть небольшое приложение с графическим интерфейсом пользователя с текстовым полем и кнопкой. Кнопка запускает функцию, которая пытается прочитать число из текстового поля. Исключение возникает, если текстовое поле пустое или содержит нечисловой текст.

Я пытаюсь отловить ошибку, если текстовое поле не имеет значения или имеет текстовое значение, а не действительное число:

calc: does [
    try [x: to integer! num_field/text]
    catch [ print "Could not get number"]
    print "Number read"
]

Следующее также не работает:

calc: does [
    try [x: to integer! num_field/text]
    throw 123
    print "Number read"
]
catch 123 [ print "Could not get number"]

Я не уверен, как использовать здесь «попробуй, брось и поймай». Я попытался проверить раздел 10 http://static.red-lang.org/red-system-specs.html, но ничего не понял.

Как это решить? Спасибо за вашу помощь.


person rnso    schedule 15.09.2017    source источник


Ответы (2)


TRY все равно будет передавать ошибку, если она сгенерирована, однако она не срабатывает, если только это не последнее вычисленное значение.

Вы можете использовать следующее:

calc: does [
    case [
        error? value: try [
            to integer! num_field/text
        ][
            ... do error handling ...
            probe make map! body-of :value
        ]

        integer? value [
            ... do successful thing ...
        ]
    ]
]

Помимо TRY, существует также ATTEMPT, который просто вернет NONE в случае возникновения ошибки. В отличие от TRY, вы не можете анализировать объект ошибки.

attempt [to integer! "Foo"]

CATCH и THROW - это больше функций управления потоком в Rebol / Red, чем обработчики ошибок, они выходят за пределы того, сколько уровней стека они пересекают:

catch [
    repeat x 10 [
        probe x
        if x = 3 [throw x]
    ]
]
person rgchris    schedule 15.09.2017
comment
Можем ли мы использовать if вместо case, если нам не нужна успешная часть (integer? value ...)? - person rnso; 15.09.2017
comment
@rnso Ага. case похож на супер-if. if error? foo: try [to integer! "Foo"][... your error handler here ...] - person rgchris; 15.09.2017

Вы можете просто использовать attempt, чтобы отловить возможные ошибки преобразования и проверить полученное значение:

calc: does [
    either integer? x: attempt [to-integer num_field/text][
        print "Number read"
    ][
        print "Could not get number"
    ]
]

Однако в этом конкретном случае есть еще более простой вариант:

calc: does [
    either integer? x: num_field/data [
        print "Number read"
    ][
        print "Could not get number"
    ]
]

Фасет /data уже содержит преобразованную версию /text или none, если преобразование невозможно, поэтому вы можете просто прочитать / записать этот фасет, чтобы числовые значения отображались в text или field лицах.

Я попытался проверить раздел 10 http://static.red-lang.org/red-system-specs.html, но ничего не понял.

Эта документация предназначена для Red / System, системного программирования DSL, встроенного в Red. Документация на языке Red находится по адресу http://docs.red-lang.org (все еще ведется тяжелая работа. ).

person DocKimbel    schedule 15.09.2017