首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

即使类和函数/方法之间没有直接链接,使用defmethod而不是defun也是合理的

当然可以。即使类和函数/方法之间没有直接链接,使用 defmethod 而不是 defun 也是合理的。这是因为 defmethod 是用于定义方法的,而 defun 是用于定义函数的。

在面向对象编程中,类和方法之间的链接是通过继承和多态实现的。当你使用 defmethod 定义一个方法时,你可以在不同的类之间共享相同的方法名称,而不需要在每个类中定义相同的函数。这样可以减少代码重复,提高代码的可维护性和可读性。

例如,假设你有一个 shape 类,它有一个 area 方法,用于计算形状的面积。你还有一个 circle 类,它继承自 shape 类。你可以使用 defmethod 定义一个 area 方法,该方法适用于所有继承自 shape 类的子类,包括 circle 类。这样,你可以在不同的类之间共享相同的方法名称,而不需要在每个类中定义相同的函数。

总之,使用 defmethod 而不是 defun 是合理的,因为它可以帮助你更好地组织和共享代码,提高代码的可维护性和可读性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

:all) 细说函数)

前言  作为一门函数式编程语言,深入了解函数定义使用自然是十分重要事情,下面我们一起来学习吧!...{},指定使用hierarchy object 2.method  具体函数实现 ;; 定义注册新函数到multimethod (defmethod multifn dispatch-val...clj/cljs函数condition map就是为我们在开发阶段提供对函数入参、函数返回值合法性断言能力,让我们尽早发现问题。...%)) user/mysum  在pre-exprs中我们可以直接指向函数入参,在post-exprs中则通过%来指向函数返回值。  ...虽然增加函数执行前提条件,而且可以针对函数值、关系、元数据等进行合法性验证,但依旧需要在运行时才能触发验证(这些不是运行时才触发还能什么时候能触发呢?)。

55490

:all) 细说函数)

前言  作为一门函数式编程语言,深入了解函数定义使用自然是十分重要事情,下面我们一起来学习吧!...{},指定使用hierarchy object 2.method  具体函数实现 ;; 定义注册新函数到multimethod (defmethod multifn dispatch-val...clj/cljs函数condition map就是为我们在开发阶段提供对函数入参、函数返回值合法性断言能力,让我们尽早发现问题。...%)) user/mysum  在pre-exprs中我们可以直接指向函数入参,在post-exprs中则通过%来指向函数返回值。  ...虽然增加函数执行前提条件,而且可以针对函数值、关系、元数据等进行合法性验证,但依旧需要在运行时才能触发验证(这些不是运行时才触发还能什么时候能触发呢?)。

36910

使用 RustC 开发 Emacs 插件

C C 是开发动态模块最直接语言,Emacs 核心部分就是用 C 开发。...为了简化数据类型在 C 与 ELisp 之间转化,Emacs 提供了一系列函数,比如: Elisp–>C 更多类型转化可参考官方文档: •Conversion Between Lisp and Module...,上面的宏使用了 Statement Expression,不是 C 语言标准,是 GNU99 扩展,但由于十分有用,大多数编译器都支持了这种语法(可通过 -std=gnu99 指定),所以可以放心使用...,不能每次重启服务来让新代码生效,但是这里通过 module-load 加载动态模块,是无法卸载,只能重启 Emacs 解决,这不是很友好,可以通过一种变通方式来实现: (defun fake-module-reload..., name)) } 相比 C 代码,这里代码简洁不少,通过 #[defun] 将 say_hello 函数导出到 ELisp 中,并且函数名自动加上了前缀 greeting ,并提供了相应 feature

79820

Emacs Lisp

前言 Lisp 是一门很古老语言 LISP 是具有悠久历史计算机编程语言家族,有独特完全括号前缀符号表示法,起源于1958年,是现今第二悠久仍广泛使用高级编程语言,只有 FORTRAN 编程语言比它更早一年...(+ 2 2) ;; Elisp中表达式可以通过括号来嵌套 (+ 2 (+ 1 1)) ;; 在lisp-interaction-mode模式中,我们可以直接计算一个表达式,计算方法是 (+ 3...,知道你退出Emacs或者改变hello定义 ;; 从下面开始,我们将不再提醒读者使用C-x C-e来定义函数执行ELisp指令 ;; 在Elisp中直接输入函数名称就是调用该函数。...; 在函数内部又使用了let函数,给一个局部变量your-name赋值 ;; 最后把参数和局部变量格式化打印出来 (defun greeting (name) (let ((your-name "...,直到buffer结束 ;; 其中t参数指示search-foward函数 跳过错误信息 直接退出 ;; 新hello-to-bonjour如下: (defun hello-to-bonjour ()

2.3K40

Emacs Lisp

前言 Lisp 是一门很古老语言 LISP 是具有悠久历史计算机编程语言家族,有独特完全括号前缀符号表示法,起源于1958年,是现今第二悠久仍广泛使用高级编程语言,只有 FORTRAN 编程语言比它更早一年...(+ 2 2) ;; Elisp中表达式可以通过括号来嵌套 (+ 2 (+ 1 1)) ;; 在lisp-interaction-mode模式中,我们可以直接计算一个表达式,计算方法是 (+ 3...,知道你退出Emacs或者改变hello定义 ;; 从下面开始,我们将不再提醒读者使用C-x C-e来定义函数执行ELisp指令 ;; 在Elisp中直接输入函数名称就是调用该函数。...; 在函数内部又使用了let函数,给一个局部变量your-name赋值 ;; 最后把参数和局部变量格式化打印出来 (defun greeting (name) (let ((your-name "...,直到buffer结束 ;; 其中t参数指示search-foward函数 跳过错误信息 直接退出 ;; 新hello-to-bonjour如下: (defun hello-to-bonjour ()

2.2K30

Emacs Lisp2

2 2);; Elisp中表达式可以通过括号来嵌套(+ 2 (+ 1 1));; 在lisp-interaction-mode模式中,我们可以直接计算一个表达式,计算方法是(+ 3 (+ 1 2));...或者改变hello定义;; 从下面开始,我们将不再提醒读者使用C-x C-e来定义函数执行ELisp指令;; 在Elisp中直接输入函数名称就是调用该函数。...;; 如果想要得到列表中第一个元素,可以使用car函数(car list-of-names);; 如果想要得到列表中除第一个元素以外其它元素,可以使用cdr函数(cdr list-of-names...,直到buffer结束;; 其中t参数指示search-foward函数 跳过错误信息 直接退出;; 新hello-to-bonjour如下:(defun hello-to-bonjour ()(switch-to-buffer-other-window...)))(other-window 1));; 执行这个函数 (boldify-names)== 帮助参考==;; 在Emacs中我们可以通过如下方式得到变量函数帮助信息;; C-h v a-variable

96740

各种编程语言对尾递归支持

/a.out 10000000000000000 10000000000000000   立即得到我们想要没有发生崩栈 20000000000000000   看来……不对,1亿亿次迭代瞬间完成...实际上,很早之前大部分C语言编译器就支持了这点,因为从技术上来看,并不是很复杂事情。C++也同理。...RESET   因为没有尾递归优化规定,所以对于那种无限循环,Common Lisp只能选择迭代才能保证不崩栈,比如使用do。...sbcl是Common Lisp另外一个实现,在这个实现中,我们使用第一个add函数版本,没有发生崩栈。...话说,awk没有对尾递归优化也属正常,而且对于内存使用还真不节制,超过了我想象。不过这也与语言目的有关,awk本就没打算做这类事情。

2.6K20

TF新工具AutoGraph:将Python转换为TensorFlow图

AutoGraph不仅仅是有用宏命令集合;它使用源代码转换来覆盖Python语言任何部分,包括控制流,函数应用赋值,生成样板代码,以及重构通顺Python以使其易于转换为图。...对于任何编译器来说,我们都要考虑错误消息可读性;为此,AutoGraph设置为创建错误消息堆栈跟踪,以显示原始源代码中错误源,不是仅显示对生成代码引用。...以下是一些代码示例,现在可以直接转换为图代码,无需任何更改。如果你想查看所有这些,可以访问下方链接。...在下面链接中可以看到这种例子,我们获取RNN训练循环并通过sess.run()调用执行它。在需要将整个训练循环传递给加速器不是通过CPU控制器管理训练情况下,这可能非常有用。...如果发现运行速度低于预期图构造,请提出问题! AutoGraph急切执行对比 在使用急切执行时,通过tf.contrib.eager.defun,你仍然可以为部分代码使用图执行。

71640

TensorFlow新功能「AutoGraph」:将Python转换为计算图

AutoGraph不仅仅是一组有用宏; 它使用源代码转换来Python任何部分,包括控制流、函数应用程序赋值、生成样板代码、以及重构常用Python代码使其容易转换为计算图。...另外,不管使用什么编译器,都需要保证报错信息可读。为此,AutoGraph设置了创建错误消息堆栈跟踪,可以帮你找到代码中错误源,不是仅仅是引用错误代码。...另外一个例子是采用RNN训练循环并通过一次sess.run()调用执行它。在需要将整个训练循环传递给加速器不是通过CPU控制器管理训练情况下,这可能很有用。...AutoGraphEager Execution 在使用eager execution时, 你仍然可以用tf.contrib.eager.defun来把部分代码转换为计算图,需要使用图形TensorFlow...将来,AutoGraph将defun无缝集成,以在eager-style代码中生成计算图。届时,你可以通过把eager代码转换为计算图片段来使用AutoGraph加速。

59830

【TensorFlow重大升级】自动将Python代码转为TF Graph,大幅简化动态图处理!

之间空白。...对于任何编译器,都会担心报错信息可读性; 为此,AutoGraph创建了报错消息堆栈跟踪,用来显示原始源代码中错误源,不仅仅是显示对生成代码参考。...注意,我们使用AutoGraph.to_graph()函数将其转换为图形原因,是为了多样性不是为了装饰。...在需要将整个训练循环传递给加速器不是通过CPU控制器管理训练情况下,这可能是很有用。 AutoGraph开辟了构建和训练模型新思路。...AutoGraphEager Execution 在使用eager execution时,你仍然可以通过tf.contrib.eager.defun对代码某些部分使用图执行。

78420

为什么Lisp语言如此先进?(译文)

三、 Fortran语言也是上个世纪50年代出现,并且一直使用至今。它代表了语言设计一种完全不同方向。Lisp是无意中从纯理论发展为编程语言,Fortran从一开始就是作为编程语言设计出来。...现在大家都觉得这是理所当然,但是Fortran I就没有这个结构,它只有基于底层机器指令goto结构。   2. 函数也是一种数据类型。...它们从此使得Lisp看上去很古怪,但也成为了这种语言最独一无二特点。Lisp古怪形式,倒不是因为它语法很古怪,而是因为它根本没有语法,程序直接以解析树(parse tree)形式表达出来。...你定义一个(class),里面有一个方法一个属性,用于替换封闭作用域(enclosing scope)中所有变量。这有点类似于让程序员自己做代码分析,本来这应该是由支持局部作用域编译器完成。...你实际上就是在做同样事,只不过划出了一个独立区域,保存累加器函数,区别只是保存在对象一个属性中,不是保存在列表(list)头(head)中。

1.2K60

TensorFlow发布重要更新AutoGraph,自动将Python转化为TF计算图

AutoGraph 不只是有用宏命令集合,它还可以使用源代码转换来覆写 Python 语言任意部分,包括控制流、函数应用分配,生成样板代码,重构惯用 Python,以使转换成图过程变得简单。...使用任意编译器,都会对错误信息可读性产生担忧;为此,AutoGraph 可以创建错误信息,并堆叠揭示原始源代码中错误来源多个轨迹,不是仅仅显示生成代码 reference。...以下有一些示例代码,它们可以直接转换为图代码不需要任何改写。如果你想实际运行这些操作,谷歌在这个 GitHub Colab 中提供了一个 notebook 可供使用。...AutoGraph Eager Execution 虽然使用 Eager Execution,你也能通过 tf.contrib.eager.defun 对部分代码根据计算图执行。...但这需要你使用 tf.cond() 这样计算图 TensorFlow ops。未来,AutoGraph 将无缝与 defun 融合,让你用简单 eager-style Python 编写图代码。

85240

面向对象编程中六大原则

` `重写(override):发生于父子类之间,指的是子类不想继承使用方法, 通过重写同一个函数实现实现对父中同一个函数覆盖,因此又叫函数覆盖。...注意重写函数必须一模一样,包括函数名、参数个数类型以及返回值,只是重写了函数实现,这也是重载区分开关键。...其中,我们称出现成员变量、方法参数、方法返回值中直接朋友,而出现在局部变量中不是直接朋友。 也就是说,陌生最好不要作为局部变量形式出现在内部。...对这六个原则遵守并不是问题,而是多问题, 也就是说,我们一般不会说有没有遵守,而是说遵守程度多少。...任何事都是过犹不及, 设计模式六个设计原则也是一样,制定这六个原则目的并不是要我们刻板遵守他们,需要根据实际情况灵活运用。 对他们遵守程度只要在一个合理范围内,就算是良好设计。

1.2K20

Checked异常Runtime异常区别_JAVA运行时异常

但是RuntimeException是非常特殊子类,你可以不用throwthrows,哪怕你throw了,也没必要thtows,即使你throws了,调用者也没必要try-catch 1> 如果在函数内容中抛出该类异常或其子类异常...如果你捕获它,就会冒这么一个风险:程序代码错误被掩盖在运行中无法察觉) 检查异常 : 一旦 用throw 抛出异常,如果当前方法 可处理异常,那么直接在该方法内用try-catch 去处理。...2、逻辑上 从逻辑角度来看, checked 异常 RuntimeException 有着不同使用目的,检查性异常 用来指示 一种调用方能够直接处理异常情况(例如: 用户输入错误,程序可以直接捕获并处理...按照所学知识,我们一般会在求面积方法,判断值合理性,如果不合理抛出异常。...但是,反过来想,如果我一开始让你传入 width length 就抛出异常呢,这个直接让你初始化对象不成功 是不是好点。

63720

6种常见测试用例设计方法及应用_测试用例设计方法

.因此,可以把全部输入数据合理划分为若干等价,在每一个等价中取一个数据作为测试输入条件,就可以用少量代表性测试数据.取得较好测试结果.等价划分可有两种不同情况:有效等价无效等价. 2...使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入输出等价边界,就是应着重测试边界情况.应当选取正好等于,刚刚大于或刚刚小于边界值作为测试数据,不是选取等价典型值或任意值作为测试数据...因果图方法 前面介绍等价划分方法边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间联系, 相互组合等. 考虑输入条件之间相互组合,可能会产生一些新情况....但要检查输入条件组合不是一件容易事情, 即使把所有输入条件划分成等价,他们之间组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件组合,相应产生多个动作形式来考虑设计测试用例....白盒测试用例设计关键是以较少用例覆盖尽可能多内部程序逻辑结果 黑盒法用例设计关键同样也是以较少用例覆盖模块输出输入接口。

98510

C++面试题

使用角度,虚函数主要用于在信息不全情况下,能使重载函数得到对应调用。构造函数本身就是要初始化实例,那使用函数没有实际意义呀。所以构造函数没有必要是虚函数。...,不是对象动态行为,也没有必要成为虚函数。...当编译器为这个构造函数产生代码时,它是为这个构造函数产生代码——既不是为基,也不是为它派生(因为不知道谁继承它)。所以它使用VPTR必须是对于这个VTABLE。...如果函数调用使用虚机制,它将只产生通过它自己VTABLE调用,不是最后VTABLE(所有构造函数被调用后才会有最后VTABLE)。 3. 什么时候需要定义虚析构函数?...析构函数同样也是成员函数,虚析构函数也会进入虚表,唯一不同是,函数名并不要求一致,而且,你如果不写,编译器也会帮你生成,而且如果基有virtual,编译器也会默认给子类添加。

1.7K42

面向对象编程会被抛弃吗?这五大问题不容忽视

20 世纪 60 年代,编程遇到了一个大问题:计算机还没有那么强大,需要以某种方式平衡数据结构程序之间能力。 这意味着,如果你有大量数据,那么不将计算机推向极限就无法充分利用这些数据。...这样就可以将一些数据和那些只在相关数据上使用函数耦合起来。 注意,这仅涵盖封装概念。也就是说,位于对象内部数据函数对于外部是不可见。...通过封装数据其他方法,面向对象编程使软件开发更加以人为中心,符合人类直觉。比如,方法 drive() 属于 car 数据组,不是 teddybear 组。之后出现继承性也很直观。...然后你会发现,这个父可能也是另一个子类,以此类推,最后要面对一堆代码。...而使用另一种范式就能够轻松地将代码简化为几行可读代码。 毫无疑问,函数式编程正在得到更多关注,面向对象编程近几年遭到一些诟病。了解新编程范式并在适当时候使用它们是很有意义

47620

【JS 口袋书】第 5 章:JS 对象生命周期秘密

即使JS中函数也是对象。...可以使用Object.create(),它会在对象之间创建链接,创建次数只有一次。 首先,咱们将greet()方法移到外面的一个对象上。...__proto__ = Person().prototype 使用空对象作为上下文调用构造函数: Person.call(obj) 检查原型链 检查JS对象之间原型链接有很多种方法。...; } 因此,可以得出结论:JS对象原型总是连接到直接“父对象”Object.prototype。没有像Python或Java这样。JS是由对象组成,那么什么是原型链呢?...这是JS一个内在特征,它从另一种称为Self语言中借用了原型系统。 当访问greet()时,JS引擎会检查该方法是否可直接在Tom上使用。 如果不是,搜索将继续向上链接,直到找到该方法

1.6K10

API设计原则 – QT官网设计实践总结

所以,子类代码代码在兼容上就会出现很多很多问题。所以,还是上面所说,其实,虚函数应该声明在接口语义里(这就是设计模式两个宗旨——依赖于接口,不是实现;钟爱于组合,不是继承。...也是为什么JavaGo语言使用interface关键字原因,C++在多态语义上非常容易滥用) 4.2.2 虚函数 vs....还有其他验证方法,比如 让别人使用API(看了文档或是先不看文档都可以) 给写文档(包含概述每个函数) 6. 命名艺术 命名很可能是API设计中最重要一个问题。应该叫什么名字?...6.2 命名 识别出所在分组,不是为每个都去找个完美的命名。...: scrollBarsEnabled(),不是areScrollBarsEnabled() 动词没有前缀,也不使用第三人称(-s): acceptDrops(),不是acceptsDrops()

2.7K20

程序员,请优先提高代码可读性

因此,必须合理考虑内存使用优化。 在大学里,我们知道了优化两个极端情况: 你可以牺牲空间来换取执行速度提升, 或者通过执行重复操作来换取内存消耗优化。...做一些没有实际价值改进。 例如,花费一周时间优化一个函数执行时间,函数在1小时内仅被调用10ms时间。 编写代码难以调试,却还要试图从中找出错误。 编写代码他人难以理解。...即使代码被良好地封装成模块//函数并且这些模块包含完全可读命令式代码,但其他人想要读懂这段代码,他们必须掌握整个代码框架以及所有使用相关技术模式。...” —— Brian Kernighan 七 代码难以跟踪 阅读代码时,通常需要频繁从一个函数跳转到另一个函数。 掌握你使用集成开发环境(IDE),可以节约很多阅读时间。...在这两者之间跳转非常不易。 依赖注入框架其他XML配置工具也是。虽然没有明确说明,但编写XML配置文件也属于编程。

93840
领券