在尝试下载文件时(例如,在stack setup下载构建计划期间或期间),堆栈(在Windows下)有时会引发以下异常:
TlsException (HandshakeFailed (Error_Protocol ("certificate has unknown CA",True,UnknownCa))).
Run Code Online (Sandbox Code Playgroud)
如果发生这个错误怎么解决?
(这已在https://github.com/commercialhaskell/stack/issues/234上讨论并解决,我正在重新提交问题以使解决方案更具可用性.)
请考虑以下示例:
case class C[T](x:T) {
def f(t:T) = println(t)
type ValueType = T
}
val list = List(1 -> C(2), "hello" -> C("goodbye"))
for ((a,b) <- list) {
b.f(a)
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我知道(运行时保证)类型a将是一些T,b并将具有C[T]相同的类型T.当然,编译器无法知道,因此我们得到了输入错误b.f(a).
要告诉编译器这个调用没问题,我们需要做一个类型转换b.f(a.asInstanceOf[T]).不幸的是,T这里不得而知.所以我的问题是:如何重写b.f(a)以使这些代码编译?
我正在寻找一个不涉及复杂结构的解决方案(以保持代码可读),并且在我们不应该依赖代码擦除来使其工作的意义上是"干净的"(参见下面的第一种方法).
我有一些工作方法,但我发现它们由于各种原因而不能令人满意.
b.asInstanceOf[C[Any]].f(a)
Run Code Online (Sandbox Code Playgroud)
这是有效的,并且具有合理的可读性,但它基于"谎言".b不是类型C[Any],我们没有得到运行时错误的唯一原因是因为我们依赖于JVM(类型擦除)的限制.我认为只有x.asInstanceOf[X]当我们知道它x真的是类型时才使用它是好的风格X.
b.f(a.asInstanceOf[b.ValueType])
Run Code Online (Sandbox Code Playgroud)
这应该根据我对类型系统的理解而有效.我已将该成员添加ValueType到类C中,以便能够显式引用type参数T.但是,在这种方法中,我们得到一个神秘的错误消息:
Error:(9, 22) type mismatch;
found : b.ValueType …Run Code Online (Sandbox Code Playgroud) 在Scala中,以下表达式引发类型错误:
val pair: (A => String, A) forSome { type A } = ( { a: Int => a.toString }, 19 )
pair._1(pair._2)
Run Code Online (Sandbox Code Playgroud)
正如SI-9899和这个答案中所提到的,根据规范,这是正确的:
我认为这是按照SLS 6.1的设计工作的:"以下skolemization规则适用于每个表达式:如果表达式的类型是存在类型T,那么表达式的类型将被假定为skolemization T."
但是,我不完全理解这一点.此规则适用于哪一点?它是否适用于第一行(即,类型pair与类型注释给出的类型不同),或者在第二行中应用(但将规则应用于第二行作为整体不会导致类型错误) ?
我们假设SLS 6.1适用于第一行.它应该skolemize存在的类型.我们可以通过将存在性放在类型参数中来使第一行中的非存在类型:
case class Wrap[T](x:T)
val wrap = Wrap(( { a: Int => a.toString }, 19 ) : (A => String, A) forSome { type A })
wrap.x._1(wrap.x._2)
Run Code Online (Sandbox Code Playgroud)
有用!(没有类型错误.)这意味着,当我们定义时,存在类型会"丢失" pair吗?没有:
val wrap2 = Wrap(pair)
wrap2.x._1(wrap2.x._2)
Run Code Online (Sandbox Code Playgroud)
这种类型检查!如果它是分配的"错误" pair,这应该不起作用.因此,它不起作用的原因在于第二行.如果是这样的话,那么wrap和pair例子有什么区别? …
在 Java 进程中,我想访问同一进程的 JDI(Java 调试接口)。
我做出以下假设:
也就是说,我想做类似的事情:
import com.sun.jdi.*
import com.sun.jdi.connect.*
VirtualMachine vm = new SelfConnector().attach()
Run Code Online (Sandbox Code Playgroud)
(当然,除了没有这样的对象。)
如何连接到我自己的虚拟机?
我希望编写一个findObj通过唯一 ID查找对象的函数。例如,如果在 Intelli/J 调试器中我看到一个变量“ x = {Something@1234}”,那么我希望能够添加一个findObj(1234)查找并返回对象的监视表达式“ ”。这样,即使在x更改变量或离开当前堆栈帧之后,我也能看到对象 #1234 。
我相信一旦我可以访问当前进程的JDI,我就可以实现这个功能。
[编辑:它没有回答问题,但它解决了我的用例:在 Intellij/J 中,您可以“标记”对象,并在监视表达式中使用这些标记。]
我已经通过SocketAttach试图连接到这个过程本身AttachingConnector使用中的Intelli / J用品的主机名和端口-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:39469,suspend=y,server=n开始在调试会话中的Java进程时的说法。(大致遵循此处描述的方法。)我得到:
Exception in thread "main" java.net.ConnectException: Connection refused
Run Code Online (Sandbox Code Playgroud)
可能是因为 Intelli/J 已经连接并且无法连接到该端口两次?[编辑:Intellij/J 使用参数启动 …