论Nim中的 proc 和 method

在Nim中。proc 是定义过程的keyword。method 是定义方法的keyword。它们之间根本的差别是proc定义的过程是静态绑定。method定义的方法是动态绑定。谈到静态绑定、动态绑定又会提到重载、重写和多态等方面的内容,假设对上述的一些概念不太理解。能够看我的上一篇博文

过程的重载:

例1:

proc print (): void =
  echo ("This is empty")

proc print (a:int): void =
  echo ("int a = ",a)

proc print (a:float): void =
  echo ("float a = ",a)

print()
print(1)
print(1.0)
Out:
This is empty
int a = 1
float a = 1.0

方法的重载:

例2:

type
  person* = ref object of RootObj
    name*:string
    age*:int

method mm(p:person): int =
  echo p.age,p.name
  echo "method"
  return 0

method mm(p:person,x:int): int =
  echo "methodint  ",x
  return 0

method mm(p:person,x:float): int =
  echo "methodfloat  ",x
  return 0

var yrs = person(name:"yrs",age:23)

discard yrs.mm()
discard yrs.mm(3)
discard yrs.mm(3.0)
Out:
23yrs
method
methodint  3
methodfloat  3.0

proc定义的过程,它的參数没有什么要求,能够没有參数,能够是基本类型,也能够是自定义的类类型。

可是method定义的方法,它的參数必须至少含有一个类类型的的參数。

也就是说method方法的模块里,必须含有类。同一时候该方法的參数至少含有一个类类型的參数。

方法的重写与多态:

例3:

#Module: tProcMethod.nim
type Animal* = ref object of RootObj
  name*: string
  age*: int

proc SelfIntroduce*(this: Animal): void = echo ("my name is animal")
method vocalize*(this: Animal): string = "..."
method ageHumanYrs*(this: Animal): int = this.age

type Dog* = ref object of Animal
proc SelfIntroduce*(this: Dog): void = echo ("my name is ",this.name)
method vocalize*(this: Dog): string = "woof"
method ageHumanYrs*(this: Dog): int = this.age * 7

type Cat* = ref object of Animal
proc SelfIntroduce*(this: Cat): void = echo ("my name is ",this.name)
method vocalize*(this: Cat): string = "meow"
#Module:testProcMethod.nim
import tProcMethod
var animals : Animal
animals = Dog(name: "Sparky", age: 10)
echo animals.name
echo animals.age
echo animals.vocalize()                 #method方法调用。是通过 实例对象引用.方法名
echo animals.ageHumanYrs()
tProcMethod.SelfIntroduce(animals)      #这里调用proc过程是用 模块名.过程名,在在Windows下用命令行执行文件时,文件名称(模块名)的全部字母被觉得是小写,
                                         #这里调用过程时要注意模块名字母的大写和小写。

在Linux下则区分大写和小写。

animals = Cat(name: "Mitten", age: 10)
echo animals.vocalize()
echo animals.ageHumanYrs()
tProcMethod.SelfIntroduce(animals)
Out:
Sparky
10
woof
70
my name is animal
neow
10
my name is animal

方法的重载、重写与多态:

例4:

type
  Far = ref object of RootObj
  bigSon = ref object of Far
  smallSon = ref object of Far
    x: int

method collide(x:Far,y:int)  =
  echo "to override!"

method collide(x: bigSon, y: int) =
  echo "big1"

method collide(x: smallSon, y: int) =
  echo "small1"

method collide(x: bigSon, y: float)  =
  echo "2"

method collide(x: bigSon, y: bigSon)  =
  echo "3"

var far: Far
var bigsona, bigsonb: bigSon
var smallsona: smallSon

new far
new bigsona
new bigsonb
new smallsona

collide(far,1)

far = bigsonb
collide(far,1)
collide(bigsona,1.0)
collide(bigsona,bigsonb)

far = smallsona
collide(far,1)
Out:
to override!
big1
2
3
small1

在例4中。第二和第三个collide方法各自是bigSon类的方法和smallSon类的方法,它们都实现了对父类方法的重写。第二、四、五collide方法是bigSon类的方法,它们实现了collide方法的重载。

由上面的两个样例能够看出。Nim中的类和方法的存在与Java和Python是不同的。它没有一个明显的界限去差别哪个方法属于哪个类,可是能够通过方法中类类型来辨别(注意动态绑定时。參数是从左至右查询的)。

这样就大大减少了程序的可读性,就像例4一样。我们能够像例3一样分开定义来添加程序的可读性。

总结:

1、过程是静态绑定。方法是动态绑定。

2、过程和方法都能重载。

3、过程可以被重写。可是不能实现多态效果。

4、方法可以被重写,可以实现多态效果。

5、注意方法和类的关系。

时间: 2024-08-08 05:22:45

论Nim中的 proc 和 method的相关文章

Android Studio中解决Gradle DSL method not found: 'android()'

最近导入as的项目出了这样的问题 这个问题困扰了我很长时间,好吧,搜了半天全都是runProguard的,最后在stackoverflow上搜到解决办法了: http://stackoverflow.com/questions/27735646/android-studio-gradle-dsl-method-not-found-android-error17-0 解决方法: 删掉最外层的build.gradle中的 android { compileSdkVersion 19 buildToo

java中的static 【method】【Variables】【Blocks】

有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象.通常情况下,类 成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用, 而不必引用特定的实例.在成员的声明前面加上关键字static(静态的)就能创建这样的 成员.如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问, 而不必引用任何对象.你可以将方法和变量都声明为static.static 成员的最常见的 例子是main( ) .因为在程序开始执行时必须调用main() ,所以它被声明为s

【转-整理】Struts2中package,action,result,method配置详解

1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 <struts> 6

java中什么是bridge method(桥接方法)

最近在看spring-mvc的源码,看到在解析handler方法的时候,有关于获取桥接方法代码,不明白什么是桥接方法,经过查找资料,终于理解了什么是桥接方法. 什么是桥接方法 桥接方法是 JDK 1.5 引入泛型后,为了使Java的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法. 我们可以通过Method.isBridge()方法来判断一个方法是否是桥接方法,在字节码中桥接方法会被标记为ACC_BRIDGE和ACC_SYNTHETIC,其中ACC_BRIDGE用于说

浅谈Java 8中的方法引用(Method References)

本人接触Java 8的时间不长,对Java 8的一些新特性略有所知.Java 8引入了一些新的编程概念,比如经常用到的 lambda表达式.Stream.Optional以及Function等,让人耳目一新.这些功能其实上手并不是很难,根据别人的代码抄过来改一下,并不要知道内部的实现原理,也可以很熟练地用好这些功能.但是当我深究其中一些细节时,会发现有一些知识的盲区.下面我就来谈一下Java 8中的Method References这个概念. 首先我给出官方对于这一概念的详细解释,https:/

ajax配置项中的type与method

1. jQuery中ajax配置项中的使用type与method的区别 本质上两个配置项是没有区别的,区别在于两者出现的时间不同,type对于目前jQuery的版本全部兼容,也就是说 1 $.ajax({ 2 type: 'POST', 3 url: '/login', 4 dataType: 'json',若出现跨域请求请使用'jsonp' 5 data: { 6 'userName': userName, 7 'password': password 8 }, 9 success: func

WebView中JS调用Android Method 遇到的坑整理

WebView是android中常用的一个组件,其作用是展示网页,并让网页和android app进行一些业务逻辑上的交互. 其坑无数,相信用过的都知道,一个一个来解决吧. 1.怎么互调: <!DOCTYPE> <html> <head> <meta charset="UTF-8"> <script type="text/javascript"> function android(bl){ if(bl){

jersey中的405错误 method not allowed

Ruby中Blocks, Proc, 和Lambdas

Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3].each { |num| puts num }