Я чувствую, что использование меток делает код очень похожим на оператор goto. Это всего лишь мысль.
Вместо этого бросьте исключение во внутренний цикл for
и инкапсулируйте два цикла for
с помощью блока try catch.
Что-то вроде
try {
// ...
for(Object outerForLoop : objectsOuter) {
// ...
for (Object innerForLoop : objectsInner) {
// ...
if (isConditionTrue)
throw new WrappedException("With some useful message. Probably some logging as well.");
}
}
catch (WrappedException) {
// Do something awesome or just don't do anything to swallow the exception.
}
Просто мысль. Я предпочитаю этот код, так как он дает мне лучшую возможность ведения журналов (как это слово) для меня, когда он запускается в производство или что-то в этом роде.
Просто проигнорируйте конструкцию exception
и определите класс исключения, то есть производный от System.Exception
, напрямую, как в C #:
type MyError(code : int, msg : string) =
inherit Exception(msg)
member e.Code = code
new (msg : string) = MyError(0, msg)
raise(MyError("Foo"))
raise(MyError("Foo", 1))
Обратите внимание, что я удалил член Msg
, потому что Exception
уже имеет эквивалентное свойство Message
.
Я не совсем понимаю, что вам нужно, но как это работает для вас?
exception Error of int * string
let ErrorC(s) = Error(0,s)
let F() =
try
let key = true
raise <| Error(42, System.String.Format("Could not parse '{0}'", key))
raise <| ErrorC(System.String.Format("Could not parse '{0}'", key))
with Error(code, msg) ->
printfn "%d: %s" code msg
Как насчет переопределения MyError как записи и использования синтаксиса записи для записи ошибки, например: -
type MyError =
{ Msg: string;
Code: int }
exception Error of MyError
raise <| Error { Msg = ( sprintf "Could not parse boolean value '%b'" key );
Code = code }