事实证明,尽管背后有非常简单的想法,但正确地使用存在/秩n类型却非常困难.
为什么需要将存在类型包装到data类型中?
我有以下简单示例:
{-# LANGUAGE RankNTypes, ImpredicativeTypes, ExistentialQuantification #-}
module Main where
c :: Double
c = 3
-- Moving `forall` clause from here to the front of the type tuple does not help,
-- error is the same
lists :: [(Int, forall a. Show a => Int -> a)]
lists = [ (1, \x -> x)
, (2, \x -> show x)
, (3, \x -> c^x)
]
data HRF = forall a. Show a => HRF …Run Code Online (Sandbox Code Playgroud) 我想在JavaFX中实现类似功能反应式编程的东西,我认为既然JavaFX已经支持属性之间的监听器和绑定,那么它应该相当容易,所以我创建了用于转换绑定的小框架,例如我现在可以做类似的事情了这个(Scala中的例子,但应该可以理解我的意思):
val property1: Property[String]
val property2: Property[Path]
Bindings.Conversions
.bindUni(property1).to(property2)
.using(p => p.getFileName.toString)
.connect()
Run Code Online (Sandbox Code Playgroud)
在这里,我通过转换函数绑定property2(是a java.nio.file.Path)的值,转换函数获取路径的最后部分并将字符串转换为property1(字符串).
这个实现非常简单(即使对于双向绑定;我只是从openjfx BidirectionalBinding类中获取一些代码,将其转换为Scala并将其调整为转换),我想知道为什么JavaFX中已经没有这样的东西了.
这一切都运行良好,我甚至可以创建这种绑定的复杂链.除非转换功能取决于某些外部状态,否则一切正常.
例如,假设您有以下绑定链:
Text field value -1-> intermediate java.nio.file.Path -2-> another String --> Label
Run Code Online (Sandbox Code Playgroud)
当文本字段更改Path并String自动重新计算时,String属性的值将写入标签.一切都很棒.但是假设-2->转换应该取决于某些复选框的切换状态:
Checkbox state ---+
|
Text field value -1-> intermediate java.nio.file.Path -2-> another String --> Label
Run Code Online (Sandbox Code Playgroud)
也就是说,当选中复选框时,转换应略有不同.
显然,直接实现这种结构是行不通的,因为更改复选框状态不会切换转换链的重新计算.但是,我发现JavaFX没有提供任何强制更改事件的方法.SimpleStringProperty例如,我尝试覆盖并暴露其fireValueChangedEvent()方法,但这没有帮助.目前我正在做这样的事情textField.setText(""); textField.setText(oldValue);,但是这是非常丑陋的,是不正确的做法,效果显着.
我错过了什么,我真的可以做我想做的事,或者根本就没有这样的东西,我完全搞砸了?
如果答案是否定的,那么我认为这严重损害了整个框架的表达能力.我知道我真的可以和很多听众一起做我想做的事情,但这很丑陋,我希望尽可能地让整个事情变得一般.
为什么对trait对象的引用不可复制?此代码编译:
struct Test;
fn clone_vec<'a>(v: Vec<&'a Test>) -> Vec<&'a Test> {
v.clone()
}
fn main() {
}
Run Code Online (Sandbox Code Playgroud)
这个没有:
trait Test {
fn do_smt(&self);
}
fn clone_vec<'a>(v: Vec<&'a Test>) -> Vec<&'a Test> {
v.clone()
}
fn main() {
}
Run Code Online (Sandbox Code Playgroud)
错误:
main3.rs:7:5: 7:14 error: failed to find an implementation of trait std::clone::Clone for &'a Test<no-bounds>
main3.rs:7 v.clone()
^~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
但是,Clone据我所知,特征是为任何类型的参考实现的:
impl<'a, T> Clone for &'a T {
/// Return a shallow copy of the reference.
#[inline]
fn clone(&self) -> &'a T …Run Code Online (Sandbox Code Playgroud) Scala Await.ready()方法定义如下:
def ready[T](awaitable: Awaitable[T], atMost: Duration): awaitable.type = ...
Run Code Online (Sandbox Code Playgroud)
也就是说,返回类型是路径依赖类型的awaitable参数.我认为(和IntelliJ IDEA同意我)这意味着如果我传递Future给函数,它应该返回Future相同的类型,事实上,它确实在简单的情况下工作:
val f: Future[Int] = Future { 10 }
val ft: Future[Int] = Await.ready(f, ???)
Run Code Online (Sandbox Code Playgroud)
这段代码编译,也就是说,Await.ready()这里真正返回Future[Int].但是,以下就不能正常工作:
val f: Future[Int] = Future { 10 }
val ft: Future[Int] = Await.ready(f.map(identity), ???)
Run Code Online (Sandbox Code Playgroud)
它失败并出现此错误:
[error] /Users/netvl/dev/work/sandbox/src/main/scala/circuit/actors/Example.scala:53: type mismatch;
[error] found : awaitable.type (with underlying type scala.concurrent.Awaitable[Int])
[error] required: scala.concurrent.Future[Int]
[error] val ft: Future[Int] = Await.ready(f.map(identity), ???)
[error] ^
Run Code Online (Sandbox Code Playgroud)
为什么会这样? …
Scala允许使用type关键字定义类型,这些类型通常具有不同的含义和目的,具体取决于声明的时间。
如果type在一个对象或一个包对象内部使用,则应定义一个类型别名,即另一种类型的简称/简称:
package object whatever {
type IntPredicate = Int => Boolean
def checkZero(p: IntPredicate): Boolean = p(0)
}
Run Code Online (Sandbox Code Playgroud)
在类/特征中声明的类型通常打算在子类/子特征中被覆盖,并且最终也被解析为具体类型:
trait FixtureSpec {
type FixtureType
def initFixture(f: FixtureType) = ...
}
trait SomeSpec extends FixtureSpec {
override type FixtureType = String
def test(): Unit = {
initFixture("hello")
...
}
}
Run Code Online (Sandbox Code Playgroud)
抽象类型声明还有其他用途,但无论如何最终它们都会解析为某些具体类型。
但是,还有一个选项可以在对象内部声明抽象类型(即,没有实际定义):
object Example {
type X
}
Run Code Online (Sandbox Code Playgroud)
与例如抽象方法相反,它可以编译:
object Example {
def method: String // compilation error
}
Run Code Online (Sandbox Code Playgroud)
由于无法扩展对象,因此永远无法将它们解析为具体类型。
我认为这样的类型定义可以方便地用作幻像类型。例如(使用Shapeless的标记类型):
import …Run Code Online (Sandbox Code Playgroud) 我的模块包含定义,其中一部分是导出的(在module子句中).我也想导出Template Haskell生成的声明.但由于似乎没有办法module用TH 修改条款,我不能这样做.
是否可以指定应该导出TH生成的声明?或者也许有其他方法可以做到这一点?
我有什么理由不能将字符串文字与字符串变量连接起来吗?以下代码:
fn main() {
let x = ~"abcd";
io::println("Message: " + x);
}
Run Code Online (Sandbox Code Playgroud)
给出了这个错误:
test2.rs:3:16: 3:31 error: binary operation + cannot be applied to type `&'static str`
test2.rs:3 io::println("Message: " + x);
^~~~~~~~~~~~~~~
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
我想这是一个非常基本且非常常见的模式,fmt!在这种情况下的使用只会带来不必要的混乱.
我不明白为什么下面的代码不能编译。似乎 rust 只是没有“扩展”类型参数,因为它看起来与我匹配。
代码(防锈围栏:http : //is.gd/gC82I4)
use std::sync::{Arc, Mutex};
struct Data{
func: Option<Box<FnMut(String) + Send>>
}
fn newData<F>(func: Option<Box<F>>) -> Data
where F: FnMut(String) + Send{
Data{
func: func
}
}
fn main(){
let _ = newData(Some(Box::new(|msg|{})));
}
Run Code Online (Sandbox Code Playgroud)
错误
<anon>:10:15: 10:19 error: mismatched types:
expected `core::option::Option<Box<core::ops::FnMut(collections::string::String) + Send>>`,
found `core::option::Option<Box<F>>`
(expected trait core::ops::FnMut,
found type parameter) [E0308]
<anon>:10 func: func
^~~~
error: aborting due to previous error
playpen: application terminated with error code 101
Run Code Online (Sandbox Code Playgroud) 考虑下面的代码示例,我有一个向量,JoinHandlers其中我需要它迭代以连接回主线程,但是,这样做我得到错误error: cannot move out of borrowed content.
let threads = Arc::new(Mutex::new(Vec::new()));
for _x in 0..100 {
let handle = thread::spawn(move || {
//do some work
}
threads.lock().unwrap().push((handle));
}
for t in threads.lock().unwrap().iter() {
t.join();
}
Run Code Online (Sandbox Code Playgroud) 最近我遇到了一个似乎很常见的问题:如何用属性和简单的文本内容来表示XML元素,如下所示:
<elem attr="aval">elemval</elem>
Run Code Online (Sandbox Code Playgroud)
使用JAXB.
我已经找到了很多关于如何做到这一点的建议,但是这些建议中的每一个都涉及手动编辑绑定类.
我有一组模式,我使用XJC将这些模式转换为Java类.但是,它似乎产生错误的代码,即它不生成设置普通内容的方法,只有设置属性的方法.
是否有可能解决XJC的这种行为?广泛的谷歌搜索对这个问题没有帮助.