问题标签 [type-bounds]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
222 浏览

scala - Scala:基于同一层次结构的另一个类型参数值限制一个参数

这个问题可能有点令人困惑,但意图是这样的:

我想将一个值限制为类型参数的层次结构中的另一个值。鉴于它们都是类型,如果可以强制执行与此类似的代码,那就太好了。

简而言之:

是有效的,但我不应该被允许为不正确的配对创建对冲。例如:

任何建议,将不胜感激。

更新:

如果在任何时候我希望我可以在 SO 中接受多个答案,那就是这个时候。所有答案都是有效的并且质量很好。我将选择最能解决问题的一个和产生最易读错误的一个。选择的答案具有可供使用的相反值(肯定会派上用场)并且不需要隐含。它还会产生最清晰的错误消息之一。类型不等式非常优雅,但是其中有一些神奇的元素,特别是它需要 2 消歧。从代码中删除它会停止工作,没有明显的原因。隐含对当然是一个很好的解决方案,它与原始问题非常相似,但不如对立那么有用且隐含免费。

感谢所有人的出色答案和快速响应。

为了完成,这里是所有重做的代码:

0 投票
1 回答
5811 浏览

scala - 在 Scala 中使用泛型实现 trait 的正确方法是什么?

我有一些简单的特征(在下面的示例中为实体),这些特征由我的应用程序中的案例类扩展。我想创建一个 EntityMapper 特征,它提供了一个接口来处理扩展实体特征的案例类(下例中的 Foo)。我认为我应该能够使用泛型和边界相当容易地做到这一点,但我已经花了几个小时在它上面,但我还没有让它正常工作。下面的代码是我认为我应该能够做的,但它因编译器错误而失败。错误是

Test.scala:15:错误:值 id 不是类型参数 Foo \ println(e.id) 的成员

我尝试了几种不同的方法来解决问题,但没有任何效果。如果我注释掉有问题的行“println(e.id)”,它会编译,但这没有用,因为我无法访问或修改 Foo 的任何属性。

我尝试使用映射器特征的协变参数,然后将类型提供给 FooMapper 对象定义,但这会产生相同的错误。该尝试的代码如下:

我也尝试通过简单的继承来实现相同的目标,但是我无法正确地将 FooMapper 中的类型参数限制为仅采用 Foos,我必须使方法签名与特征完全匹配,这就是为什么我开始尝试使用泛型来实现它的原因类型绑定。该尝试的代码如下:

返回的错误代码是:

Test.scala:13:错误:无法创建对象,因为方法在 trait EntityMapper 类型(e:experiment.Entity)experiment.Entity 中未定义

(注意experiment.Entity不匹配experiment.Foo:包experiment中的类Foo是包experiment中traitEntity的子类,但方法参数类型必须完全匹配。)

任何帮助将不胜感激。我正在使用 Scala 版本 2.10.3。

0 投票
1 回答
95 浏览

scala - 验证泛型类型参数是否符合 2 个不相关的类型

在 Scala 中,可以为泛型参数指定类型绑定。

例如,要确保A符合,SomeType1可以执行以下操作:

现在,假设我需要确保它A符合 2 个不相关的类型SomeType1SomeType2.

有没有办法做到这一点?

0 投票
1 回答
178 浏览

scala - Scala:使用类型参数或抽象类型作为类型边界

假设我有:

这编译:

这失败了:

...和:

我尝试使用抽象类型而不是类型参数,结果相同。我发现的唯一解决方法是实例化类型。这编译:

不幸的是,我正在使用没有运行时实例的幻像类型,通常是出于性能原因。

为什么 Scala 会在这里产生编译错误?有更好的解决方法吗?

谢谢你的帮助。

更新:除了下面的解决方法之外,我还需要一种方法来覆盖具有抽象类型边界的类型。我这样做是这样的:

0 投票
2 回答
89 浏览

scala - 如何保证伴生对象中存在方法并引用它?

考虑这个示例,其中Listable旨在混合到案例类的伴随对象中。因此,为了调用Writer.grid,必须有一个A扩展的伴生对象Listable[A],并在其中implicit Writer[A]定义。(例如,将任意列表转换为ListableCSV 格式。)

这是一个天真的实现:

这可以编译,但不能工作,因为listable: A真正指的是 object Test,而Ainw: Writer[A]指的是 case class Test,所以调用Writer.grid(Test)不符合类型边界。

Listable我可以通过放弃并要求implicit List[A]签名来解决这个问题grid

但我更愿意:

  1. 不需要这样一个可能产生意外结果的隐式函数。
  2. 不要使用特殊类型来 wrap list,因为它也会在其他地方使用。
  3. grid将方法的定义保留Listable.

是否可以重新签名Writer.grid以使其工作?(或其他结构变化)

0 投票
1 回答
47 浏览

scala - Scala 类型界限“单级”

让我们像这样定义一个层次结构:

试图定义这样的特征:

导致编译错误:

有人可以解释一下为什么会发生这种情况,以及如何解决它吗?

更新

无法删除类型边界。它们是必要的,因为一些隐含的东西不会起作用。

0 投票
1 回答
643 浏览

scala - 强制“排除”超类型的下限

Scala 中的边界允许对 Scala 中的类型进行更精细的控制,例如参数类型。例如

以上允许函数接受作为字符串子类型的参数,也

上面允许设置上限和下限,以便 S 是 B 的子类型和 A 的超类型。

我的问题是(我假设边界是包容性的)是否可以设置一个参数类型,以便该参数是说 String 的超类型,但不包括一些下界的超类型(在这种情况下是 String)说键入任何。

更新

我希望使用 arg2 的调用应该导致非法参数异常。

0 投票
2 回答
926 浏览

scala - Scala 的类型推断如何与类型边界一起工作?

当类型参数上存在类型边界时,Scala 究竟如何确定要推断的类型?例如:

尝试使用此功能时,例如:

me将具有推断的类型MouseEvent。的类型界限T是下限类型,所以T必须是 的类型MouseEvent或超类型MouseEvent,那么为什么me推断类型为MouseEvent?它不应该推断出最普​​遍的类型吗?

关于 Scala 的类型推断是如何工作的,这是我没有得到的东西吗?还是我对类型边界的理解完全错误?

编辑:

假设我们进一步将 T 的类型限制为 的子类型Event,其中Event是 的超类型MouseEvent。所以我们得到:

所以如果我们这样做

其中MouseDragEvent是 的子类型MouseEvent,编译失败并出现类型错误,正如预期的那样,因为绑定确保它me必须是 的超类型MouseEvent

然而,如果我们这样做

编译成功。明明Any不是 的子类型Event,那为什么编译会成功呢?什么是推断类型T

0 投票
0 回答
257 浏览

scala - Scala:覆盖有边界的类型成员

我已将我的问题缩小到以下最小(非)工作示例:

它是一种更高种类的 F 有界多态性(我使用 T[E] 作为某些方法的返回值)。当我尝试编译此代码时,我得到:

但是,鉴于它D是 and 的子类型,B并且它E被传递给Band C,这些类型不应该是不兼容的。Martin Odersky 在这个问题中解释说,在 mixin 中合并成员时,有两条规则:1)具体优于抽象,2)线性化顺序。在这种情况下,两者都是“具体”类型,所以我们选择 2)。但是线性化顺序说C应该会胜过B,所以我想知道我在这里做错了什么。

0 投票
2 回答
93 浏览

scala - Scala 类型边界 =:=

虽然编译:

这抱怨类型不匹配,预期T,实际Int,好像它忽略了类型绑定。

为什么?