是否可以从隐式类定义自动生成用于互操作的配套 Java 静态方法?
例如:
class Foo()
object FooOps {
implicit class FooOps(foo: Foo) extends AnyVal {
def baz = "hello"
}
}
Run Code Online (Sandbox Code Playgroud)
可以作为new Foo().baz. 然而,这在 Java 中是相当不方便和不惯用的。是否可以为 Java 自动生成(例如通过宏)静态方法,就像 Kotlin 为扩展方法所做的那样?例如:
object FooOps {
@MagicAnnotation
implicit class FooOps(foo: Foo) extends AnyVal {
def baz(n: Int) = "hello"
}
// generated:
def baz(foo: Foo, n: Int) = foo.baz(n)
}
Run Code Online (Sandbox Code Playgroud) 使用《Swift 语言指南:扩展》中的示例代码我已经像这样扩展了 struct Double
extension Double {
func someFunc() {
print("someFunc")
}
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶这个声明
2.someFunc()
Run Code Online (Sandbox Code Playgroud)
没有生成编译时错误,例如:“Int”类型的值没有成员“someFunc”。我预计 2 的值会隐式转换为 Int,但 Swift 将其转换为 Double。这是为什么 ?Swift 如何确定本例中 2 的值是 Double 类型?
然后我尝试像这样调用 someFunc()
let x = 2
x.someFunc()
Run Code Online (Sandbox Code Playgroud)
这里我得到了预期的编译时错误
这是否与Swift 编程语言 3.0.1:语言指南:基础知识:类型安全和类型推断中的陈述相矛盾?
类型推断使编译器能够在编译代码时自动推断出特定表达式的类型,只需检查您提供的值即可。
编辑
从响应中我了解到发生这种情况是因为 Double 符合 ExpressibleByIntegerLiteral 协议。然而 Float 结构也确实符合它以及其他一些类型。下面我创建了也符合该协议的结构。然而最终在编译时选择了 Double。为什么?一个扩展的方法相对于其他扩展的方法的优先级是如何确定的?
struct someStruct: ExpressibleByIntegerLiteral{
var i:Int = 0
init(integerLiteral value: Int64){
i = Int(value)
}
}
extension someStruct {
func someFunc() {print("Somestruct someFunc") }
}
extension Double { …Run Code Online (Sandbox Code Playgroud) 我有一个计算数字类型的平方和的函数,如下所示。
import cats.syntax.functor._
import cats.syntax.applicative._
import cats.{Id, Monad}
import scala.language.higherKinds
object PowerOfMonads {
/**
* Ultimate sum of squares method
*
* @param x First value in context
* @param y Second value in context
* @tparam F Monadic context
* @tparam T Type parameter in the Monad
* @return Sum of squares of first and second values in the Monadic context
*/
def sumOfSquares[F[_]: Monad, A, T >: A](x: F[A], y: F[A])(implicit num: Numeric[T]) : F[T] = {
def …Run Code Online (Sandbox Code Playgroud) 我现在在 Redux 中的 combineReducers 上收到以下错误。
缺少类型注释A。A是在函数类型 [1] 中声明的类型参数,并在调用combineReducers[2] 时隐式实例化。
代码如下所示,但出现在我所有使用 combineReducers 的减速器中。
export default combineReducers({
status: ((state: boolean = true, action: Action) => {
switch (action.type) {
case 'START_SESSION':
case 'REFRESH_AUTH_SUCCEEDED':
case 'SIGN_IN_FAILED':
case 'SIGN_OUT':
return false;
default:
return state;
}
}: Reducer<*>),
});
Run Code Online (Sandbox Code Playgroud)
我相信这是因为 Redux flow-types 中的这种类型定义
declare export function combineReducers<O: Object, A>(reducers: O):
CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
Run Code Online (Sandbox Code Playgroud)
我相信这与 Flow 的发布有关,版本 0.85.0 引入了一些与“隐式实例化”有关的东西。
我阅读了 Flow 自己的 Sam Goldman 在 Medium …
在我的项目中,我有一个 type A,用于一些地方的参数,我希望一堆类型自动转换为该类型。我已经使用A. 我已经删除了触发问题所不需要的所有内容:
trait A
object A {
implicit class SeqA[T](v: Seq[T])(implicit x: T => A) extends A
implicit class IntA(v: Int) extends A
implicit class TupleA(v: (Int, Int)) extends SeqA(Seq(v._1, v._2))
}
Run Code Online (Sandbox Code Playgroud)
但scalac由于非法循环引用而拒绝此代码:
$ scalac -version
Scala compiler version 2.12.8 -- Copyright 2002-2018, LAMP/EPFL and Lightbend, Inc.
$ scalac A.scala
A.scala:5: error: illegal cyclic reference involving class TupleA
implicit class TupleA(v: (Int, Int)) extends SeqA(Seq(v._1, v._2))
^
one error found
Run Code Online (Sandbox Code Playgroud)
这里究竟有什么问题?什么是编译器绑定到涉及 …
我正在扩展一个抽象类,它在其构造函数中定义了一个隐式参数。
似乎有 3 种不同的方法可以做到这一点:
abstract class Base(z: ZType)(implicit a: AType)
// Explicit
class First(z: ZType, a: Atype) extends Base(z)(a)
// Explicitly pass a into the child class which
// implicitly passes it into the parent class
class Second(z: ZType, implicit val a: AType) extends Base(z)
// Implicitly passed into both
class Third(z: ZType)(implicit a: AType) extends Base(z)
Run Code Online (Sandbox Code Playgroud)
也许这取决于将如何使用子类。就我而言,子类不会有隐含AType的作用域,所以我倾向于第二种选择。
我对第二个选项最大的担忧是,我现在为同一类型定义了 2 个隐式,一个在父类中,一个在子类中。由于它们始终是同一个对象,这有什么影响吗?出于任何原因,我应该避免第二种模式吗?
基本上,这里是否有“正确”的模式,或者所有这些都可以接受,具体取决于它们所使用的代码的上下文?
我正在尝试创建一个 ZIO 模块的示例,它有两个实现:
我的通用界面如下所示:
trait Service[R] {
def load[T <: Component](ref: CompRef): RIO[R, T]
}
Run Code Online (Sandbox Code Playgroud)
现在我的 YAML 实现看起来像:
def loadYaml[T <: Component: Decoder](ref: CompRef): RIO[Any, T] = {...}
Run Code Online (Sandbox Code Playgroud)
这Decoder是特定于实现的。
现在的问题是如何从 Service 实现委托给loadYaml.
我尝试了以下方法:
val components: Components.Service[Any] = new Components.Service[Any] {
implicit val decodeComponent: Decoder[Component] =
List[Decoder[Component]](
Decoder[DbConnection].widen,
...
).reduceLeft(_ or _)
def load[T <: Component](ref: CompRef): RIO[Any, T] = loadYaml[T] (ref)
}
Run Code Online (Sandbox Code Playgroud)
这给了我:
Error:(62, 20) could …Run Code Online (Sandbox Code Playgroud) 该阶语言规范,第7.2节是有关隐式范围:这解释了隐式范围内的是在某种方式与类型的部件相关联的模块T。下面列出了 T 的组成部分。其中之一是
if
T表示隐式转换为具有参数类型T1,…,Tn和结果类型的方法的类型U,T1,…,Tn 和 U 的部分的并集;
我不能从这个头或尾。我不明白类型 T 如何表示隐式转换。
隐式范围规范的这部分是什么意思?
给定以下 Peano 数的类型级加法函数
sealed trait Nat
class O extends Nat
class S[N <: Nat] extends Nat
type plus[a <: Nat, b <: Nat] = a match
case O => b
case S[n] => S[n plus b]
Run Code Online (Sandbox Code Playgroud)
说我们想证明定理
对于所有自然数 n,n + 0 = n
也许可以这样指定
type plus_n_0 = [n <: Nat] =>> (n plus O) =:= n
Run Code Online (Sandbox Code Playgroud)
那么在为定理提供证据时,我们可以很容易地向 Scala 编译器询问特定情况下的证据
summon[plus_n_O[S[S[O]]]] // ok, 2 + 0 = 2
Run Code Online (Sandbox Code Playgroud)
但是我们如何询问 Scala 是否可以为 的所有实例生成证据[n <: Nat],从而提供 的证明plus_n_0?
目前正在学习 Scala 3 隐式,但我很难理解 \xe2\x80\x8bas和with关键字在如下定义中的作用:
given listOrdering[A](using ord: Ordering[A]) as Ordering[List[A]] with\n \xe2\x80\x8bdef compare(a: List[A], b: List[A]) = ...\nRun Code Online (Sandbox Code Playgroud)\n我尝试谷歌搜索,但没有找到任何好的解释。我已经检查了 Scala 3 参考指南,但我发现的唯一一件事as是它是一个“软修饰符”,但这并不能真正帮助我理解它的作用......我猜as在上面的代码以某种方式用于澄清这listOrdering[A]是一个Ordering[List[A]](就像正在进行某种类型的打字或类型转换?),但如果能找到它背后的真正含义那就太好了。
至于with,我只在 Scala 2 中使用它来继承多个特征(class A extends B with C with D),但在上面的代码中,它似乎以不同的方式使用......
非常感谢任何解释或为我指明查看文档的正确方向!
\n另外,如果用 Scala 2 编写上面的代码会是什么样子?也许这可以帮助我弄清楚发生了什么事......
\n