正确使用Character/isWhitespace的用法包括:
(Character/isWhitespace \a) => false
(Character/isWhitespace \ ) => true
Run Code Online (Sandbox Code Playgroud)
但是,我的第一次尝试是这个,我发现错误令人困惑.
(Character/isWhitespace "")
=> IllegalArgumentException No matching method found: isWhitespace
=> clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
Run Code Online (Sandbox Code Playgroud)
这IllegalArgument部分是有道理的,但为什么它说"找不到匹配的方法"?显然,该功能确实存在.
我问这个问题的原因是我是Clojure的新手,并认为我从根本上误解了一些东西.
当我输入时(Character/isWhitespace \a),我认为我所说的是:"我知道有一个Character命名空间,并且在其中有一个被调用的函数isWhitespace,我想调用该函数并传入\a".
在这个心智模型上,我上面的结果令人困惑,因为Clojure似乎在说,"每当你给我一个这个函数不接受的参数类型时,我就会假装该函数不存在." 例如,"你不允许混合砖块,所以如果你试试,我会给你一个BlenderDoesntExist错误." 这很奇怪.
一些答案似乎暗示了这一点
Character/isWhitespace只是一部分的什么Clojure的使用查找功能,而另一部分则是参数的类型.(我已经做了一些搜索:这可能是一种多方法吗?)一个很好的答案将为我澄清这个过程.
Gui*_*ler 10
clojure编译器依赖于反射,以便为Java互操作类方法找到匹配的签名,并且当找不到任何内容时,它会引发它自己的异常.
在这种情况下,IllegalArgumentException正确引发了a,但是noMethodReport显示的错误消息会导致混淆.
而这个负责它的源代码在clojureGitHub库.
首先,Java互操作解析演练.
当clojure解析器找到.点宏时,HostExpr解析器处理解析,该解析尝试确定第二个参数是符号还是类.
如果它是一个类,则假定它是被调用的类的静态方法,并继续解析StaticMethodExpr.
解析器内部的第一件事是尝试通过对类的反射来查找方法:
List methods = Reflector.getMethods(c, args.count(), methodName, true);
if(methods.isEmpty())
throw new IllegalArgumentException("No matching method: " + methodName);
Run Code Online (Sandbox Code Playgroud)
它正确找到它并且在那时没有引发异常
然后它将参数添加到找到的方法:
java.lang.reflect.Method m = (java.lang.reflect.Method) methods.get(i);
params.add(m.getParameterTypes());
Run Code Online (Sandbox Code Playgroud)
之后尝试查找匹配方法签名索引:
methodidx = getMatchingParams(methodName, params, args, rets);
Run Code Online (Sandbox Code Playgroud)
对于这种情况,返回'-1'并method保持为空.这就是解析阶段.
评估时间......
然后,当invokeStaticMethod被调用时,它调用getMethods在Reflector.java其正确找到"isWhitespace"两个匹配的签名.
最后你看到的令人困惑的信息,内部功能:
static Object invokeMatchingMethod(String methodName, List methods, Object target, Object[] args)
Run Code Online (Sandbox Code Playgroud)
测试找到的方法参数匹配,试图找到具有适当签名的方法:
for(Iterator i = methods.iterator(); i.hasNext();)
{
m = (Method) i.next();
Class[] params = m.getParameterTypes();
if(isCongruent(params, args))
Run Code Online (Sandbox Code Playgroud)
如果未找到匹配的签名,则引发异常
if(m == null)
throw new IllegalArgumentException(noMethodReport(methodName,target));
Run Code Online (Sandbox Code Playgroud)
所以答案是clojure编译器依赖于反射来找到方法的匹配签名,并且当没有找到任何东西时它会引发它自己的异常.
在这种情况下,IllegalArgumentException正确引发了a,但是noMethodReport显示的错误消息会导致混淆.
Character/isWhitespace是一种Java方法(类的静态方法java.lang.Character).有关调用Java方法的语法示例,请参阅Java interop.
虽然常规Clojure函数仅由其名称定义,但Java方法由其签名定义,其签名由其名称及其参数的数量和类型组成.
Character类中isWhitespace定义的方法的唯一变体是和.所以用字符串调用"没有匹配的方法" .isWhitespace(char ch)isWhitespace(int codepoint)isWhitespace
| 归档时间: |
|
| 查看次数: |
6403 次 |
| 最近记录: |