为什么 Clojure 对非法参数说“没有匹配方法”?

2023-11-27

Character/isWhitespace 的正确用法包括:

(Character/isWhitespace \a) => false
(Character/isWhitespace \ ) => true

然而,我的第一次尝试是这样的,我发现这个错误令人困惑。

(Character/isWhitespace "")
  =>  IllegalArgumentException No matching method found: isWhitespace
  => clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)

The IllegalArgument部分是有道理的,但为什么它说“找不到匹配的方法”?显然这个函数确实存在。

澄清

我问这个问题的原因是我是 Clojure 的新手,并且认为我从根本上误解了某些东西。

当我打字时(Character/isWhitespace \a),我什么think我想说的是:“我知道有一个Character命名空间,其中有一个名为的函数isWhitespace,我想调用该函数并传入\a".

在这个心理模型上,我上面的结果令人困惑,因为 Clojure 似乎在说:“每当你给我一个该函数不接受的参数类型时,我就会假装该函数不存在。”例如,“你不允许混合砖块,所以如果你尝试,我会给你一个 BlenderDoesntExist 错误。”这很奇怪。

有些答案似乎暗示

  • 名字Character/isWhitespace只是partClojure 使用什么来查找函数,另一部分是参数的类型。 (我做了更多搜索:这可能是一种多种方法吗?)
  • 正在 Java 类上查找该方法吗?

一个很好的答案将为我澄清这个过程。


tl;dr

clojure 编译器依赖反射来查找 Java 互操作类方法的匹配签名,并且当找不到任何内容时,它会引发自己的异常。

在这种情况下IllegalArgumentException是正确提出的,但是noMethodReport显示错误消息会导致混乱。

And 这是负责它的源代码 on the clojuregithub 仓库。

长版

首先,Java 互操作解析演练。

当 clojure 解析器发现.点宏HostExpr解析器处理解析,它尝试确定第二个参数是符号还是类。

如果它是一个类,则假定它是被调用的类的静态方法,并且解析继续StaticMethodExpr.

解析器内的第一件事是尝试通过类的反射来查找方法:

  List methods = Reflector.getMethods(c, args.count(), methodName, true);
  if(methods.isEmpty())
      throw new IllegalArgumentException("No matching method: " + methodName);

它正确找到并此时没有引发任何异常

然后它将参数添加到找到的方法中:

  java.lang.reflect.Method m = (java.lang.reflect.Method) methods.get(i);
  params.add(m.getParameterTypes());

之后尝试找到匹配的方法签名索引:

  methodidx = getMatchingParams(methodName, params, args, rets);

对于这种情况返回“-1”并且method保持为空。这就是解析阶段。

评价时间...

那么当invokeStaticMethod被调用,它调用getMethods on Reflector.java它正确地找到“isWhitespace”的两个匹配签名。

最后是您在函数内部看到的令人困惑的消息:

 static Object invokeMatchingMethod(String methodName, List methods, Object target, Object[] args)

对找到的方法进行参数匹配测试,尝试找到具有正确签名的方法:

 for(Iterator i = methods.iterator(); i.hasNext();)
   {
    m = (Method) i.next();
    Class[] params = m.getParameterTypes();
    if(isCongruent(params, args))

如果没有找到匹配的签名,则会引发异常

if(m == null)
   throw new IllegalArgumentException(noMethodReport(methodName,target));

因此,答案是 clojure 编译器依赖反射来查找方法的匹配签名,并且当找不到任何内容时,它会引发自己的异常。

在这种情况下IllegalArgumentException是正确提出的,但是noMethodReport显示错误消息会导致混乱。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Clojure 对非法参数说“没有匹配方法”? 的相关文章

随机推荐

  • 为什么 Window.FindName() 没有发现子 UserControl 中按钮的 x:Name?又名名称范围如何工作?

    因此 在下面的示例代码中 我创建了一个 UserControl UserControldChild 它是主窗口 Window1 xaml 的子窗口 为什么FindName 方法在下面的代码中找不到 myButton 这一定与WPF XAML
  • 在 Rails 应用程序中记录 RestClient

    我想调试我的 Rails 应用程序发出的请求休息客户端 RestClient 文档说 要启用日志记录 您可以 使用 ruby Logger 设置 RestClient log 或者设置一个环境变量以避免修改代码 在这种情况下 您可以使用文件
  • UUID 有多独特?

    使用 UUID 唯一标识某些内容 我将其用于上传到服务器的文件 有多安全 据我了解 它是基于随机数的 然而 在我看来 只要有足够的时间 它最终会重演 纯粹是偶然 是否有更好的系统或某种类型的模式来缓解这个问题 非常安全 the annual
  • Java(Android)中自动检测文本的语言[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 对于我的应用程序 我希望给定一个文本 检测其语言 例如 ISO 代码和机会 我想知道是否有某种网络服务或java库可以这样做 提前致谢 使用二元分析
  • movl $_start, %eax 是什么意思?

    后面跟一个标识符是什么意思 x86 汇编 AT T 语法 在 AT T 语法中 意味着将后面的内容视为立即常量而不是内存地址 换句话说 movl start eax 加载符号的地址 start进入 eax movl start eax 从内
  • 如何为 python 获取 PIP [重复]

    这个问题在这里已经有答案了 我正在尝试安装 pip py 每当我搜索安装程序时 它都会打开一个新选项卡 其中包含代码 但我无法下载任何内容 我打算做什么 我打算将代码复制粘贴到Python解释器中吗 如何让它适用于 Windows 7 32
  • 在 Python 2.7 中从数字列表中删除一组索引的最有效方法是什么?

    所以我想知道如何使用 Python 2 7 最有效地获取用于表示索引的值列表 如下所示 但长度最多为 250 000 indices 2 4 5 并从更大的列表中删除该索引列表 如下所示 3 000 000 项 numbers 2 6 12
  • 如何在Linux上高效监控目录变化?

    我正在使用 Magento 有一个功能可以将 CSS 和 Javascript 合并到一个大文件中 不管其优点和缺点 都存在以下问题 最终文件会在多个级别进行缓存 包括但不限于 亚马逊云前 代理服务器 客户端浏览器缓存 Magento 使用
  • Aurelia 语义下拉菜单

    我正在尝试在 Aurelia 中使用组合框 以便我的用户可以输入下拉列表并搜索内容 我试图合并 Semantic 创建的下拉菜单 但是当我在元素上调用下拉菜单时 它不会运行代码 因此它仍然是一个正常的下拉菜单 就像这里的状态示例一样 htt
  • R 从面板中删除行,同时保持面板平衡

    有没有一种优雅的方法来平衡不平衡的面板数据集 我想从一个不平衡的面板 即 有些人丢失了一些数据 开始 最后得到一个平衡的面板 即 所有的人都没有丢失任何数据 下面是一些示例代码 正确的最终结果是保留对 Frank 和 Edward 的所有观
  • 如何从 Blazor 服务器端下载内存中文件

    有没有办法下载动态生成的文件在记忆中 in Blazor 服务器端不需要将其存储在文件系统上 解决方案是添加Web Api控制器到 Blazor 服务器端应用程序中 Add Controllers DownloadController cs
  • Android TabHost 上的徽章

    我想实现与 iPhone 中相同的功能 我在底部栏中实现了与 iPhone 中相同的自定义 Tabhost 我可以设置 正常 选定状态的两个图标 但我需要带有数量的动态图标 通知如图片所示 Thanks Android ViewBadger
  • 增强named_mutex和remove()命令

    我有一个可以由多个线程创建的类 但在一个函数中 代码需要受到保护 因此我决定使用 boost 进程间互斥体 每个类在其构造函数中创建或打开相同的互斥体 MyClass MyClass boost interprocess named mut
  • 对于布尔字段,其 getter/setter 的命名约定是什么?

    Eg boolean isCurrent false 你将它的 getter 和 setter 命名为什么 假设你有 boolean active 访问器方法是 public boolean isActive return this act
  • 依赖属性强制绑定问题

    我同时安装了 VS2008 和 VS2010 我看到一个非常奇怪的行为 在 VS2008 中 我有一个简单的 WPF 应用程序
  • 显示时未转换 Unicode

    我正在将应用程序本地化为西班牙语 并且使用 Unicode 在该语言的 Localized strings 文件中对字符进行编码 例如 我有以下条目 login saveSettings Guardar configuraci u00F3n
  • PHP 标头(位置:...):强制地址栏中的 URL 更改

    我目前正在开发一个移动网站 该网站使用 PHP 会话与数据库进行身份验证 我有一个登录页面 其中包含一个表单 可以转到服务器登录 php提交时 然后 php 文件创建一些会话数据 存储在 SESSION 中 并将用户重定向回索引页面 hea
  • 为什么 printf 在调用后不会刷新,除非格式字符串中有换行符?

    为什么printf除非格式字符串中有换行符 否则调用后不会刷新 这是 POSIX 行为吗 我怎么可能有printf每次都立即冲水 The stdout默认情况下 流是行缓冲的 因此只会在到达换行符 或被告知时 后显示缓冲区中的内容 您有几个
  • Flutter 如何将图像文件保存到图库中的新文件夹?

    我想在从相机获取文件后将图像保存在图库中 如何创建一个新目录并保存我们从相机获取的图像文件 Future getImageCamera async var imageFile await ImagePicker pickImage sour
  • 为什么 Clojure 对非法参数说“没有匹配方法”?

    Character isWhitespace 的正确用法包括 Character isWhitespace a gt false Character isWhitespace gt true 然而 我的第一次尝试是这样的 我发现这个错误令人