false (Character/isWhitespace \ ) => -6ren">
gpt4 book ai didi

clojure - 为什么 Clojure 会说 "no matching method"表示非法参数?

转载 作者:行者123 更新时间:2023-12-02 21:29:15 26 4
gpt4 key购买 nike

Character/isWhitespace 的正确用法包括:

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

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

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

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

澄清

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

当我输入 (Character/isWhitespace\a) 时,我认为是说:“我知道有一个字符 命名空间,其中有一个名为 isWhitespace 的函数,我想调用该函数并传入 \a”。

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

一些答案​​似乎暗示着这一点

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

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

最佳答案

tl;dr

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

在这种情况下,会正确引发 IllegalArgumentException,但会显示 noMethodReport 错误消息,这会导致困惑。

this is the source code responsible for itclojure github 存储库上。

长版本

首先,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 时,它会在 Reflector.java 上调用 getMethods,从而正确找到“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 错误消息,这会导致困惑。

关于clojure - 为什么 Clojure 会说 "no matching method"表示非法参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19590432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com