标签: implicit

伴侣对象中的隐式视图

我正在阅读Joshua D. Suereth的Scala In Depth,并且在scala中遇到了关于隐式视图的以下代码:

object test {
  trait Foo
  trait Bar
  object Foo {
    implicit def fooToBar(f : Foo) =  new Bar{ }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后定义一个需要Bar作为参数的方法:

def bar(x : Bar) = println("bar")
Run Code Online (Sandbox Code Playgroud)

为什么以下工作:

val f = new Foo{}
bar(f) // print "bar"
Run Code Online (Sandbox Code Playgroud)

但

bar(new Foo{})
Run Code Online (Sandbox Code Playgroud)

会导致编译器给出类型不匹配错误:

error: type mismatch;
found   : java.lang.Object with test.Foo
required: test.Bar
          bar(new Foo {})
              ^
Run Code Online (Sandbox Code Playgroud)

scala implicit

4
推荐指数
1
解决办法
498
查看次数

超特征的隐式参数解析

我正在尝试使用隐式参数将依赖项"注入"到我的类中,如下所示:

trait Bar {
    def m:String
}

object Bar {
    implicit val objBar = new Bar{ val m = "from object" } 
}

trait FooTrait { 
    def aBar(implicit bar:Bar) = bar
    def go = { aBar.m }
}
Run Code Online (Sandbox Code Playgroud)

这里编译器FooTrait从Bar伴随对象中的隐式val 提供隐式参数.这样做:

scala> println((new FooTrait{}).go)
from object
Run Code Online (Sandbox Code Playgroud)

给我我期望的结果.但是,如果我混合FooTrait和另一个特征如:

trait SuperFoo {
    implicit val superBar = new Bar{ val m = "from super" }
}
Run Code Online (Sandbox Code Playgroud)

结果是一样的:

scala> println((new FooTrait with SuperFoo).go)
from object
Run Code Online (Sandbox Code Playgroud)

我认为编译器会SuperFoo在尝试通过检查Bar的伴随对象来解析隐式参数之前查看.这篇博客文章 …

scala implicit

4
推荐指数
1
解决办法
5992
查看次数

当方法调用后定义隐式val时,Scala隐式参数为null

考虑:

object implicitnull extends App {
  mymethod

  implicit val arg = "foo"

  def mymethod(implicit arg: String) = {
    arg.size
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,这不会导致任何编译错误,而是在运行时导致NullPointerException来自arg.size.

这是预期的行为吗?

scala implicit

4
推荐指数
1
解决办法
1156
查看次数

使用隐式作为类型约束

据我所知,有两种方法可以添加类型约束.

trait Dummy
Run Code Online (Sandbox Code Playgroud)

第一种方式

def doStuff[T <: Dummy](x: T) = x
Run Code Online (Sandbox Code Playgroud)

第二种方式

def doStuff[T](x: T)(implicit x: T <:< Dummy) = x
Run Code Online (Sandbox Code Playgroud)

两者都达到了相同的效果.

我只是想知道我应该直接使用上限或下限的哪种场景,或者我应该使用implicit来在类型上附加约束.

scala implicit

4
推荐指数
1
解决办法
100
查看次数

Antlr语法,解析器规则中的隐式令牌定义

一件奇怪的事情正在发生。我定义了语法,这是节选。

name  
   : Letter                 
   | Digit name              
   | Letter name          
   ;

numeral  
   : Digit                
   | Digit numeral         
   ;

fragment  
Digit  
   : [0-9]  
   ;  

fragment  
Letter  
   : [a-zA-Z]  
   ;
Run Code Online (Sandbox Code Playgroud)

那么为什么它只对我引用一个片段的两行(字母和数字名称)显示警告,而下面的其他行完全正确...

parsing antlr definition implicit token

4
推荐指数
1
解决办法
3204
查看次数

DSL提取案例类字段名称

我正在尝试构建DSL,但我遇到了一个问题:它适用于案例类,但我想知道提取案例类字段名称的最简单方法.我想到的一个想法是使用宏来丰富我的Case类的类型,但我不愿意.

trait QueryDSL[CC] {

  def meta: CC

  implicit object StringIsFieldType extends Field[CC, String] {
    def name = "FakeNAME"
  }

  implicit def implQuery[V](b: V): Query[CC] = new Query[CC](meta)
  implicit def implField[V](b: V)(implicit ev: Field[CC, V]): QueryField[CC, V] = new QueryField(ev)
}

case class Query[CC](meta: CC, clauses: List[Clause[_]] = Nil) {

  def setProperty[F](clause: CC ? Clause[F]): Query[CC] = copy(clauses = clause(meta) :: clauses)
}

trait Field[V, M] extends scala.AnyRef {
  def name: scala.Predef.String
}

abstract class Clause[V](val fieldName: String, value: V)
case …
Run Code Online (Sandbox Code Playgroud)

dsl scala implicit case-class scala-macros

4
推荐指数
1
解决办法
550
查看次数

foldRight后的无形HList地图

类型级别foldRight工作正常(getLabelWithValues),后续类型级别map(getValues)也可以正常工作.如果我在一个方法(getValuesFull)中组合两者,它就不再起作用了.丢失的是什么?

完整的源代码(sbt准备好~run使用隐式调试输出)在这里:https://github.com/mpollmeier/shapeless-playground/tree/8170a5b

case class Label[A](name: String)
case class LabelWithValue[A](label: Label[A], value: A)

val label1 = Label[Int]("a")
val labels = label1 :: HNil

object combineLabelWithValue extends Poly2 {
  implicit def atLabel[A, B <: HList] = at[Label[A], (B, Map[String, Any])] {
    case (label, (acc, values)) ?
      (LabelWithValue(label, values(label.name).asInstanceOf[A]) :: acc, values)
  }
}

object GetLabelValue extends (LabelWithValue ~> Id) {
  def apply[B](labelWithValue: LabelWithValue[B]) = labelWithValue.value
}

val labelsWithValues: LabelWithValue[Int] :: HNil = getLabelWithValues(labels) …
Run Code Online (Sandbox Code Playgroud)

scala implicit shapeless

4
推荐指数
1
解决办法
220
查看次数

什么时候Scala可以隐式返回null?

当Scala的调用implicitly在运行时返回null时,我最近感到很惊讶.我认为这是不可能的,因为如果在隐式范围内没有可用的隐式实例,代码就不应该编译.何时隐式允许返回null?这是编译器限制,还是这种预期的行为?

如果有帮助,这里有一些背景信息.我正在使用无形来派生类型类实例来持久化任意嵌套的case类.我认为在嵌套的case类中隐式使用来检查是否可以派生类型类实例是有帮助的,因为可能不清楚从哪里开始查看嵌套的case类是否很大.

所以,例如,如果我试图坚持:

case class Foo(bar: Bar, baz: Baz)
Run Code Online (Sandbox Code Playgroud)

并且编译器无法为我的格式化程序派生一个实例MyFormatter[Foo],我开始做类似以下的事情:

case class Bar(i: Int, q: Qux)
object Bar {
  implicit val formatter = implicitly[MyFormatter[Bar]]
}
Run Code Online (Sandbox Code Playgroud)

期望编译器告诉我它找不到隐式实例MyFormatter[Bar].

相反,这是一个可怕的想法,我的代码编译(当它不应该,因为没有Qux的类型类实例可以派生)并且Bar.formatter在运行时为null.

scala implicit typeclass shapeless

4
推荐指数
1
解决办法
276
查看次数

IdentityServer4 PostLogoutRedirectUri为null

我试图让隐式流程为IdentityServer4工作.登录和注销正常工作,但PostLogoutRedirectUri返回null,尽管设置了需要设置的值.我想要的是注销过程在注销完成后重定向回我的应用程序.

我正确获取logoutId,Logout调用BuildLoggedOutViewModelAsync:

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Logout(LogoutInputModel model)
    {
        var vm = await _account.BuildLoggedOutViewModelAsync(model.LogoutId);
...
Run Code Online (Sandbox Code Playgroud)

此方法位于我的AccountService.cs类中,然后调用DefaultIdentityServiceInteractionService的GetLogoutContextAsync:

public async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)
    {
        // get context information (client name, post logout redirect URI and iframe for federated signout)
        var logout = await _interaction.GetLogoutContextAsync(logoutId);
...
Run Code Online (Sandbox Code Playgroud)

这会创建一个IdentityServer4.Models.LogoutRequest.

该SignOutIFrameUrl字符串属性设置为"http://localhost:5000/connect/endsession/callback?sid=bf112f7785bc860fcc4351893012622e&logoutId=d6649e7f818d9709b2c0bc659696abdf",但没有别的似乎都在LogoutRequest被填充.

不幸的是,这意味着它PostLogoutRedirectUri是null并且AutomaticRedirectAfterSignOut也是null,并且当LoggedOut.cshtml加载页面时,signout-callback.js永远不会加载该文件:

@section scripts
{
    @if (Model.AutomaticRedirectAfterSignOut)
    {
        <script src="~/js/signout-redirect.js"></script>
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的配置设置.

Config.cs:

public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        { …
Run Code Online (Sandbox Code Playgroud)

c# implicit identityserver4 oidc-client-js

4
推荐指数
2
解决办法
4710
查看次数

如果def名称为toString,则Scala隐式def不起作用

此代码无法编译:

object Foo {
  implicit def toString(i: Int): String = i.toString      
  def foo(x: String) = println(x)
  foo(23)
}    
Run Code Online (Sandbox Code Playgroud)

上面的代码无法编译,但有以下错误:

error: type mismatch;
found   : scala.this.Int(23)
required: String
  foo(23)
Run Code Online (Sandbox Code Playgroud)

但是,这段代码编译

object Foo {
  implicit def asString(i: Int): String = i.toString      
  def foo(x: String) = println(x)
  foo(23)
}
Run Code Online (Sandbox Code Playgroud)

为什么名称implicit def应该重要?

注意:如果该方法被命名equals,它也不会工作,但它的作品,如果它被命名hashCode或clone等

scala implicit

4
推荐指数
1
解决办法
412
查看次数