Nim 튜토리얼[13] (조사: 블로그에 광고 좀 시켜줄래요?)

6501 단어 자습서

유형 변환


Nim은 디스플레이 유형 변환 및 암시적 유형 변환을 지원합니다.
카스트 조작부호를 사용하여 디스플레이 형식 변환 작업을 완성합니다.
디스플레이 형식 변환 작업은 컴파일러가 완성한 작업이고 비트 모드입니다
스텔스 형식 변환도 컴파일러가 완성한 작업이지 비트 모드가 아니다
다음 코드를 보도록 하겠습니다.
proc getID(x: Person): int =
  Student(x).id

위 코드에서
만약 x 변수의 유형이 Student 유형이 아니라면 (Person 유형은 Student 유형의 부모 유형)
그러면 InvalidObjectConversionError 예외가 발생합니다.

객체 변형


일반적으로 가변 객체 유형은 실제적으로 더 큰 의미를 가집니다.
(역주: 이것은 대상을 대상으로 하는 3대 요소 중 하나인'다태적'의 중요한 구성 부분이다)
다음 코드를 보십시오.
# This is an example how an abstract syntax tree could be modelled in Nim
type
  NodeKind = enum  # the different node types
    nkInt,          # a leaf with an integer value
    nkFloat,        # a leaf with a float value
    nkString,       # a leaf with a string value
    nkAdd,          # an addition
    nkSub,          # a subtraction
    nkIf            # an if statement
  Node = ref NodeObj
  NodeObj = object
    case kind: NodeKind  # the ``kind`` field is the discriminator
    of nkInt: intVal: int
    of nkFloat: floatVal: float
    of nkString: strVal: string
    of nkAdd, nkSub:
      leftOp, rightOp: PNode
    of nkIf:
      condition, thenPart, elsePart: PNode

var n = PNode(kind: nkFloat, floatVal: 1.0)
# the following statement raises an `FieldError` exception, because
# n.kind's value does not fit:
n.strVal = ""

위의 코드에서 볼 수 있다
상속 관계가 있는 대상 간에 유형 변환을 하는 것은 매우 간단하다
잘못된 대상 속성에 접근하면 이상이 발생합니다

메서드


대상의 방법에는 두 가지 결점이 있다
  • 프로그래머는 운행 기간에 하나의 유형으로 추가하기 어렵다(또는 추악한 방법으로만 할 수 있다)
  • 방법의 매개 변수가 확실하지 않을 때가 많다
  • Nim은 유사한 문제를 피하기 위해 분류에 방법을 분배하지 않습니다
    나중에 Nim의 동적 바인딩 방법의 특성을 알아보겠습니다.

    방법 호출


    점 조작부호를 사용하여 대상을 호출할 수 있는 방법
    obj.method(args)
    ... 이 아니라
    method(obj,args)
    매개 변수가 없으면 괄호를 생략할 수 있습니다
    obj.method
    메소드 호출은 객체의 제한을 받지 않습니다. 다음 코드를 보십시오.
    echo("abc".len) # is the same as echo(len("abc"))
    echo("abc".toUpper())
    echo({'a', 'b', 'c'}.card)
    stdout.writeln("Hallo") # the same as writeln(stdout, "Hallo")

    대상을 향한 작법을 다시 한 번 보도록 하겠습니다.
    import strutils
    
    stdout.writeln("Give a list of numbers (separated by spaces): ")
    stdout.write(stdin.readLine.split.map(parseInt).max.`$`)
    stdout.writeln(" is the maximum!")

    기분 나쁘지 않아요?

    등록 정보


    대상의 속성을 알아보려면 아래 코드를 보십시오
    type
      Socket* = ref object of RootObj
        FHost: int # cannot be accessed from the outside of the module
                   # the `F` prefix is a convention to avoid clashes since
                   # the accessors are named `host`
    
    proc `host=`*(s: var Socket, value: int) {.inline.} =
      ## setter of hostAddr
      s.FHost = value
    
    proc host*(s: Socket): int {.inline.} =
      ## getter of hostAddr
      s.FHost
    
    var s: Socket
    new s
    s.host = 34  # same as `host=`(s, 34)

    이 Socket 유형, host 속성이 있습니다. 이 속성의 값을 가져올 때
    두 번째 방법을 실행하고 이 속성의 값을 설정할 때 첫 번째 방법을 실행합니다
    (이 예에서도 inline 방법을 보여 주었다)
    우리는 그룹과 유사한 속성을 제공하기 위해 형식에 네모난 괄호를 다시 불러올 수 있다
    다음 코드를 참조하십시오.
    type
      Vector* = object
        x, y, z: float
    
    proc `[]=`* (v: var Vector, i: int, value: float) =
      # setter
      case i
      of 0: v.x = value
      of 1: v.y = value
      of 2: v.z = value
      else: assert(false)
    
    proc `[]`* (v: Vector, i: int): float =
      # getter
      case i
      of 0: result = v.x
      of 1: result = v.y
      of 2: result = v.z
      else: assert(false)

    동적 할당 방법


    proc 키워드 대신 method 키워드를 사용해야 합니다
    동적 할당 기능을 사용할 수 있습니다
    다음 코드를 보도록 하겠습니다.
    type
      PExpr = ref object of RootObj ## abstract base class for an expression
      PLiteral = ref object of PExpr
        x: int
      PPlusExpr = ref object of PExpr
        a, b: PExpr
    
    # watch out: 'eval' relies on dynamic binding
    method eval(e: PExpr): int =
      # override this base method
      quit "to override!"
    
    method eval(e: PLiteral): int = e.x
    method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b)
    
    proc newLit(x: int): PLiteral = PLiteral(x: x)
    proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b)
    
    echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))

    다음 코드를 보도록 하겠습니다.
    type
      Thing = ref object of RootObj
      Unit = ref object of Thing
        x: int
    
    method collide(a, b: Thing) {.inline.} =
      quit "to override!"
    
    method collide(a: Thing, b: Unit) {.inline.} =
      echo "1"
    
    method collide(a: Unit, b: Thing) {.inline.} =
      echo "2"
    
    var a, b: Unit
    new a
    new b
    collide(a, b) # output: 2

    결의는 왼쪽에서 오른쪽으로 집행되기 때문이다
    그래서 마지막 collide 방법이 앞의 두 가지 collide 방법보다 낫다.
    어쨌든 a와 b는 유닛 타입이니까.
    주의: Nim은 허위 방법표를 만들지 않습니다. (C#.net은 허위 방법표가 필요합니다.)
    하지만 호출 트리가 생성됩니다(이렇게 하면 성능을 향상시킬 수 있습니다)

    좋은 웹페이지 즐겨찾기