Nimチュートリアル【14】
4936 ワード
ネットユーザー@沈没して魚を捕って、1台のサーバーを賛助しました
このシリーズのチュートリアルが終わったら、Nimのコミュニティの構築に着手します~
異常
Nimの例外タイプはオブジェクトタイプです
慣例によれば、Nimの例外タイプの名前はError接尾辞で終わるべきである.
システムモジュールで例外タイプを定義したベースクラス
すべての異常はsystemから派生しなければならない.Exceptionタイプ
異常オブジェクトのライフサイクルが分からないため、
メモリスタックに例外のインスタンスにスペースを割り当てる必要があります
コンパイラでは、開発者がスタックに異常なスペースを割り当てることはできません.
異常を投げ出すには、この異常のmsg属性に値を付けなければなりません.
約束通り、非常に特殊な場合に限って異常を引き起こすべきだ.
例えば、ファイルが開かないために異常を起こすべきではありません.
このファイルは存在しない可能性があるからです.
raise文による例外
raise文を使用して異常を起こすことができます
次のコードを見てください
raiseキーワードの後ろにドルが付いている場合、例外のインスタンスが表示されます.
最後の異常を再び引き起こす
SystemモジュールではnewExceptionの方法も定義されています
以下のコードを見てください:(かなり簡略化されているのではないでしょうか)
try文取得異常
try文で例外をキャプチャできます
tryコードブロックのコードが実行されると、実行時に例外が発生します.
対応するexcept文が実行されます
次のexcept文にこの例外が明確にリストされていない場合
では、最後の空のexcept文を自分で実行します.
これはif else文に似ているように見えます
finally文が存在する場合、
finally文ブロック内のコードはどうしても実行されます
異常が処理されていない場合
この異常はスタックから上へ伝播します
これは、呼び出しチェーン上のメソッドが実行されない可能性があることを意味する.
(もし彼が実行されたら、彼はfinallyの句の中にいるに違いない)
例外オブジェクトにアクセスする必要がある場合
システムモジュールのgetCurrentExceptionメソッドまたはgetCurrentExceptionMsgメソッドを使用できます.
次のサンプルコードを見てみましょう
方法の上で異常についての注釈をします
{.raises.}を使うとある方法に注釈をつけた.
コンパイル期間中にこのメソッド(またはこのメソッドが呼び出されたメソッド)が異常を投げ出すかどうかを検出します.
できる場合、コンパイルはパスしません.
サンプルコードは次のとおりです.
この一節は私もあまり理解していないので,みんなは自分で原文を見ましょう.
汎用型
Nim言語の方法パラメータ化,反復器,などの特性は言語そのものの汎用特性によって実現される.
この特性は強いタイプの容器に非常に有用である.
コードを見てみましょう
上の例では、汎用ツリーを示します.
この例では、メソッドの汎用化、汎用反復器などの特性をカッコで行うことができます.
このシリーズのチュートリアルが終わったら、Nimのコミュニティの構築に着手します~
異常
Nimの例外タイプはオブジェクトタイプです
慣例によれば、Nimの例外タイプの名前はError接尾辞で終わるべきである.
システムモジュールで例外タイプを定義したベースクラス
すべての異常はsystemから派生しなければならない.Exceptionタイプ
異常オブジェクトのライフサイクルが分からないため、
メモリスタックに例外のインスタンスにスペースを割り当てる必要があります
コンパイラでは、開発者がスタックに異常なスペースを割り当てることはできません.
異常を投げ出すには、この異常のmsg属性に値を付けなければなりません.
約束通り、非常に特殊な場合に限って異常を引き起こすべきだ.
例えば、ファイルが開かないために異常を起こすべきではありません.
このファイルは存在しない可能性があるからです.
raise文による例外
raise文を使用して異常を起こすことができます
次のコードを見てください
var
e: ref OSError
new(e)
e.msg = "the request to the OS failed"
raise e
raiseキーワードの後ろにドルが付いている場合、例外のインスタンスが表示されます.
最後の異常を再び引き起こす
SystemモジュールではnewExceptionの方法も定義されています
以下のコードを見てください:(かなり簡略化されているのではないでしょうか)
raise newException(OSError, "the request to the OS failed")
try文取得異常
try文で例外をキャプチャできます
# read the first two lines of a text file that should contain numbers
# and tries to add them
var
f: File
if open(f, "numbers.txt"):
try:
let a = readLine(f)
let b = readLine(f)
echo "sum: ", parseInt(a) + parseInt(b)
except OverflowError:
echo "overflow!"
except ValueError:
echo "could not convert string to integer"
except IOError:
echo "IO error!"
except:
echo "Unknown exception!"
# reraise the unknown exception:
raise
finally:
close(f)
tryコードブロックのコードが実行されると、実行時に例外が発生します.
対応するexcept文が実行されます
次のexcept文にこの例外が明確にリストされていない場合
では、最後の空のexcept文を自分で実行します.
これはif else文に似ているように見えます
finally文が存在する場合、
finally文ブロック内のコードはどうしても実行されます
異常が処理されていない場合
この異常はスタックから上へ伝播します
これは、呼び出しチェーン上のメソッドが実行されない可能性があることを意味する.
(もし彼が実行されたら、彼はfinallyの句の中にいるに違いない)
例外オブジェクトにアクセスする必要がある場合
システムモジュールのgetCurrentExceptionメソッドまたはgetCurrentExceptionMsgメソッドを使用できます.
次のサンプルコードを見てみましょう
try:
doSomethingHere()
except:
let
e = getCurrentException()
msg = getCurrentExceptionMsg()
echo "Got exception ", repr(e), " with message ", msg
方法の上で異常についての注釈をします
{.raises.}を使うとある方法に注釈をつけた.
コンパイル期間中にこのメソッド(またはこのメソッドが呼び出されたメソッド)が異常を投げ出すかどうかを検出します.
できる場合、コンパイルはパスしません.
サンプルコードは次のとおりです.
proc complexProc() {.raises: [IOError, ArithmeticError].} =
...
proc simpleProc() {.raises: [].} =
...
この一節は私もあまり理解していないので,みんなは自分で原文を見ましょう.
汎用型
Nim言語の方法パラメータ化,反復器,などの特性は言語そのものの汎用特性によって実現される.
この特性は強いタイプの容器に非常に有用である.
コードを見てみましょう
type
BinaryTreeObj[T] = object # BinaryTree is a generic type with
# with generic param ``T``
le, ri: BinaryTree[T] # left and right subtrees; may be nil
data: T # the data stored in a node
BinaryTree*[T] = ref BinaryTreeObj[T] # type that is exported
proc newNode*[T](data: T): BinaryTree[T] =
# constructor for a node
new(result)
result.data = data
proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
# insert a node into the tree
if root == nil:
root = n
else:
var it = root
while it != nil:
# compare the data items; uses the generic ``cmp`` proc
# that works for any type that has a ``==`` and ``<`` operator
var c = cmp(it.data, n.data)
if c < 0:
if it.le == nil:
it.le = n
return
it = it.le
else:
if it.ri == nil:
it.ri = n
return
it = it.ri
proc add*[T](root: var BinaryTree[T], data: T) =
# convenience proc:
add(root, newNode(data))
iterator preorder*[T](root: BinaryTree[T]): T =
# Preorder traversal of a binary tree.
# Since recursive iterators are not yet implemented,
# this uses an explicit stack (which is more efficient anyway):
var stack: seq[BinaryTree[T]] = @[root]
while stack.len > 0:
var n = stack.pop()
while n != nil:
yield n.data
add(stack, n.ri) # push right subtree onto the stack
n = n.le # and follow the left pointer
var
root: BinaryTree[string] # instantiate a BinaryTree with ``string``
add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
add(root, "world") # instantiates the second ``add`` proc
for str in preorder(root):
stdout.writeln(str)
上の例では、汎用ツリーを示します.
この例では、メソッドの汎用化、汎用反復器などの特性をカッコで行うことができます.