我有一个函数,它接受泛型类型的一个参数,我想访问它的类:
fun <T> test(t: T) {
t::class
}
Run Code Online (Sandbox Code Playgroud)
这失败了"类文字中的表达式具有可空类型".没关系,我明白了(我可以Any?用作我的T和null价值).
但是,如果我将其更改t为非null的保证,它仍会失败并显示相同的错误消息:
fun <T> test(t: T) {
t!!::class
}
Run Code Online (Sandbox Code Playgroud)
在哪种情况下t!!::class还会造成麻烦?
有没有办法在不使用Any(或者转换为Any)的情况下获取类?
我有一个提供Restriction-object 的特定方法(在哪里Restriction是一个接口).由于它的实现已经是测试,我只想测试我的方法是否实际上提供了一个对象RestrictionImpl.
我看到有一些我可以assertThat和它一起使用的匹配器,我想,匹配器isA是想要完成这项任务的东西.
简化我的代码看起来像这样:
public static Restriction getRestriction() {
return new RestrictionImpl();
}
Run Code Online (Sandbox Code Playgroud)
我的测试看起来像那样;
@Test
public void getRestriction_returnsRestrictionImpl() {
assertThat(getRestriction(), isA(RestrictionImpl.class));
}
Run Code Online (Sandbox Code Playgroud)
但是这不会编译.我所能做的就是测试,如果a RestrictionImpl是Restriction......但是没有必要这样做.
我误解了目的isA吗?它的意义是什么?
更新:
使用assertThat(getRestriction(), is(instanceOf(RestrictionImpl.class)))会工作,但我认为这isA是一个快捷方式.以我想要的方式
打电话assertThat需要它有签名assertThat(T, Matcher<? extends T>),但它的签名是assertThat(T, Matcher<? super T>)
有没有一种方法可以获取传递给when语句的表达式的值?
在我的应用程序中,我有一个KeyListener类似的
_content.addKeyListener(object : KeyAdapter() {
override fun keyPressed(e: KeyEvent?) = when(e?.keyCode) {
KeyEvent.VK_T -> mainWindow.enterTrainingState()
KeyEvent.VK_P -> mainWindow.enterPlayState()
KeyEvent.VK_E -> mainWindow.close()
else -> println(e?.keyCode)
}
})
Run Code Online (Sandbox Code Playgroud)
Kotlin是否可以使用整洁的语法e?.keyCode?我真的不想重复这种表达。
我想在F#中编写一个解析器,因为我必须使用Antlr.这意味着我必须Visitor为每个要解析的AST节点定义一个类.现在我遇到了一些问题,即存在一些循环依赖的规则,例如:
boolExpr : boolTerm 'or' boolTerm ;
boolTerm : boolAtom 'and' boolAtom ;
boolAtom : '(' boolExpr ')'
| ... ;
Run Code Online (Sandbox Code Playgroud)
这意味着我需要3个具有相同循环依赖关系的访问者类,并且我希望将每个访问者类放在他们自己的文件中
//BoolExprVisitor.fs
let boolExprVisitor = { new BaseVisitor<AST.BoolExpr>() with
override __.VisitBoolExpr(context: BoolExprContext) =
context.boolTerm() |> mapAccept boolTermVisitor |> AST.BoolExpr
}
//BoolTermVisitor.fs
let boolTermVisitor = { new BaseVisitor<AST.BoolTerm>() with
override __.VisitBoolTerm(context: BoolTermContext) =
context.boolAtom() |> mapAccept boolAtomVisitor |> AST.BoolTerm
}
//BoolAtomVisitor.fs
let boolAtomVisitor = { new BaseVisitor<AST.BoolAtom>() with
override __.VisitBoolAtom(context: BoolAtomContext) =
context.boolExpr() |> accept boolExprVisitor |> AST.BoolAtom …Run Code Online (Sandbox Code Playgroud) 为了在后面的步骤中创建更好的错误消息,我想保存解析器成功的位置以及文本.获取位置似乎很容易(因为有getPosition解析器),但我不知道如何访问文本.
假设我有这种类型来保存位置
type SourceLocation = {
from: Position
to: Position
text: string
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个函数,它将SourceLocation另一个解析器的结果添加到:
let trackLocation (parser: Parser<'A, 'B>): Parser<SourceLocation * 'A, 'B> =
let mkLocation ((start: Position, data: 'A), stop: Position: 'Positon) =
let location = { from = start; to = stop } // how do I get the text?
in (location, data)
getPosition .>>. parser .>>. getPositon |>> mkLocation
Run Code Online (Sandbox Code Playgroud)
由于解析器只是函数,CharStream我认为我可以将流与Index我的位置一起使用来获取文本,但我没有看到获取此文本的方法.
那么获取解析器成功的文本的正确方法是什么?
如果我有一个通用函数返回a T或一些默认值,我想使用??运算符
T f<T>(T a, T b)
{
return a ?? b;
}
Run Code Online (Sandbox Code Playgroud)
消息失败
运算符“ ??” 不能应用于'T'和'T'类型的操作数
我认为这是因为T可能无法为空。但我还要假设??上面的运算符应该执行与
T f<T>(T a, T b)
{
var a_ = a;
return a_ != null ? a_ : b;
}
Run Code Online (Sandbox Code Playgroud)
第二个代码可以毫无问题地进行编译。
那么,为什么这些案件即使应该采取同样的措施也要以不同的方式处理?
我有一个泛型函数,需要实例化其泛型参数的对象并将其传递给某个接口的实例。
据我所知,实例化通用对象的唯一方法是使函数内联并具体化该类型参数。但我不想公开该接口的实现。
问题是内联函数不能使用内部类。
我基本上想要的是这样的:
/* The interface I want to expose */
interface Params<T> {
val doc: T
}
/* The implementation I do not want to expose */
internal class ParamsImpl<T> (override val doc: T) : Params<T>
/* The function */
inline fun <reified T> doSomething(init: Params<T>.() -> Unit) {
val doc= T::class.java.newInstance()
val params = ParamsImpl(doc) // Can't compile since ParamsImpl is internal
params.init()
}
Run Code Online (Sandbox Code Playgroud) 我有一个记录类型,它经常出现在嵌套的复杂数据结构中.因为记录类型有一个自动生成ToString的ToString我更大的结构变得混乱的方式,我不关心我的记录的字符串表示.
所以我希望有一个空字符串作为我的记录的表示.覆盖ToString似乎没有做任何事情,使用StructuredFormatDisplay不能使用空字符串,因为它需要输入表单"Text {Field} Text".现在我有
[<StructuredFormatDisplay("{}")>]
type MyRecord
{ 5 fields... }
override __.ToString () = ""
Run Code Online (Sandbox Code Playgroud)
但这导致了The method MyRecord.ToString could not be found.
那么没有记录类型的字符串表示的正确方法是什么?
我有一个带有两个参数的构造函数的类型:
type Foo = Foo of int * int
Run Code Online (Sandbox Code Playgroud)
我可以用一个元组来称呼它(int, int).
let foo = Foo(1,2)
Run Code Online (Sandbox Code Playgroud)
但在我的情况下,我想部分应用构造函数在管道中使用它
let someFunc param =
calculateSomeInt param
|> Foo 42 //error
Run Code Online (Sandbox Code Playgroud)
但这是不可能的,因为构造函数不能以curry形式调用.
是否有可能告诉F#我想要以咖喱形式构造函数而不必定义新函数let fooCtr a b = Foo (a,b)?
如何测试方法是否无效.例如,我有一个静态方法,如果给定的字符串参数为null或为空(它用于参数验证),则抛出异常.现在我的测试看起来像这样:
@Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
assertTrue(true); // <- this looks very ugly
}
@Test(expected = IllegalArgumentException.class)
public void notNullOrEmpty_throwsExceptionIfValueIsNull() {
Require.notNullOrEmpty(null);
}
@Test(expected = IllegalArgumentException.class)
public void notNullOrEmpty_throwsExceptionIfValueIsEmpty() {
Require.notNullOrEmpty("");
}
Run Code Online (Sandbox Code Playgroud)
如何在没有通话的情况下让第一个测试通过assertTrue(true),有一个Assert.fail()类似的东西Assert.pass()?
编辑:添加缺少(expected = IllegalArgumentException.class)第3测试