结果类型是泛型类型上的类型投影的隐式转换

     2023-03-23     230

关键词:

【中文标题】结果类型是泛型类型上的类型投影的隐式转换【英文标题】:Implicit conversion where there resulting type is a type projection on a generic type 【发布时间】:2021-10-27 02:32:42 【问题描述】:

我有一些基本上可以归结为这个的 scala 2.13 代码

import scala.language.implicitConversions

trait Base 
  type V
  def v: V


case class Derived(v: Int) extends Base 
  type V = Int



object TestImplicitConversion 
  implicit def getV[T <: Base](a: T): T#V = a.v

  val a: Int = Derived(5)


这里我希望编译器使用隐式转换getVDerived 转换为Int,但是代码无法编译。手动添加对getV 的调用将使代码编译。有人可以帮我理解为什么在标准中解释了转换。

我发现进行这种转换的方法是添加第二个通用参数和一个约束

implicit def getV2[T <: Base, S](a: T)(implicit constraint: T#V =:= S): S = constraint(a.v)

在这个版本中,编译器使用转换并且代码会编译。

编辑:

@user 使用细化类型提供的替代解决方案确实看起来是一种更好的方法。但它并没有真正提供为什么它的原始实现不起作用的答案。所以我仍然有兴趣了解为什么编译器在显式调用将使代码编译时不使用隐式 def。

【问题讨论】:

只是一个提示,尽量避免使用通用类型投影,它是unsound,这里有一些examples。 Scala 3 丢弃一般类型的投影。最好利用依赖路径的类型,例如:implicit def getV[T &lt;: Base](a: T): a.V = a.v @gianlucaaguzzi 将类型投影T#V 替换为路径相关类型a.V 没有帮助。斯卡拉 2.13.6。 @DmytroMitin 对我来说似乎是work。 @user 你删除了implicit。当然,通过显式调用它可以工作。 @user 如果删除implicit,则无需将类型投影替换为路径相关类型。显式调用甚至可以使用类型投影。 【参考方案1】:

正如 gianluca aguzzi 在 cmets 中提到的那样,类型投影是不可靠的,应该避免。此外,T 不是具体类型,因此无论如何您都不能在其上使用投影。您可以只接受Base#V 作为类型参数,并为a 的类型使用细化类型:

implicit def get[T](a: Base  type V = T ): T = a.v

因此,您可以避免投射和类型投影。

Scastie

【讨论】:

有一种假设,只要不与下界/交集类型混合,类型投影就会保持正确github.com/lampepfl/dotty-feature-requests/issues/14lptk.github.io/programming/2019/09/13/type-projection.html 我不确定 OP 的实际需求,但最初的问题是关于隐式转换。 @DmytroMitin 啊,这很有趣!让我们希望这最终在 Scala 3 中实现。 @DmytroMitin 我删除了依赖于路径的类型部分并编写了仅 Scala 2 的答案(使用使用 Scala 2 而不是 Scala 3 的 Scastie),我将添加一个 Scala 3稍后。 我认为这里提供的这种方法比原始问题中使用的方法更好。但我仍然想了解为什么原始版本不起作用。因为在 scala 2.13 中显式添加调用将按预期编译和工作。

泛型类型的隐式转换?

】泛型类型的隐式转换?【英文标题】:Implicitconversionforgenerictype?【发布时间】:2013-12-2212:03:44【问题描述】:考虑这个功能:defjustTrue[T,S](seq:S)(implicitev:S<:<Seq[T])=truejustTrue(List(1,2,3))>>true它有效。但是为什么不能用同一... 查看详情

javascript的数据类型的隐式转换

什么是弱类型语言?计算机语言的类型可以分为强类型和弱类型两种。二者之间的区别,就在于计算时,不同类型数据是否可以透明的隐式转换。如果一个语言可以隐式转换它的所有类型,那么它的变量、表达式等在参与运算时... 查看详情

警告:从枚举类型“UIInterfaceOrientation”到不同枚举类型“UIDeviceOrientation”的隐式转换?

】警告:从枚举类型“UIInterfaceOrientation”到不同枚举类型“UIDeviceOrientation”的隐式转换?【英文标题】:warning:Implicitconversionfromenumerationtype\'UIInterfaceOrientation\'todifferentenumerationtype\'UIDeviceOrientation\'?【发布时间】:2011-10-1900:39:50 查看详情

从枚举类型 'enum UIViewAnimationOption 到不同枚举类型 uiviewanimation 的隐式转换

】从枚举类型\\\'enumUIViewAnimationOption到不同枚举类型uiviewanimation的隐式转换【英文标题】:implicitconversionfromenumerationtype\'enumUIViewAnimationOptiontodifferentenumerationtypeuiviewanimationtransition从枚举类型\'enumUIViewAnimationOption到不同枚 查看详情

隐式类型转换

...工作的时候,写错了一条sql,判断某varchar类型的字段=2,结果匹配了很多条数据,比如selectttfromtable1wherett=2;结果集tt中有“2sssss”、“2dddddd”等。当时是很好奇,后面去查阅了资料,才发现这是mysql隐式转换导致的。那么什么... 查看详情

[2016-02-08][javascript][数据类型的隐式转换]

[2016-02-08][javascript][数据类型的隐式转换]转换成布尔类型undefined->falsenull->false0|0.0->falseNaN->false长度为0的字符串(空字符串)->false其他对象->true转换成数值类型undefined->NaNnull->0true->1false->0字符串内 查看详情

Oracle sql中的隐式和显式数据类型转换有啥区别

】Oraclesql中的隐式和显式数据类型转换有啥区别【英文标题】:whatisthedifferencebetweenimplicitandexplicitdatatypeconversioninOraclesqlOraclesql中的隐式和显式数据类型转换有什么区别【发布时间】:2016-07-1513:17:58【问题描述】:我需要知道Orac... 查看详情

javascript中的隐式类型转化

javascript中的隐式类型转化 #隐式转换##“+”字符串和数字如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用`ToPrimitive`抽象操作... 查看详情

什么是泛型

...p;5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter)。声明的类型参数在使用时用具体的类型来替换。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。创建集合时... 查看详情

为啥我可以阻止基元而不是用户定义类型的隐式转换?

】为啥我可以阻止基元而不是用户定义类型的隐式转换?【英文标题】:WhycanIpreventimplicitconversionsforprimitivesbutnotuser-definedtypes?为什么我可以阻止基元而不是用户定义类型的隐式转换?【发布时间】:2017-05-1521:55:45【问题描述】... 查看详情

向量从一种类型到另一种c ++的隐式转换

】向量从一种类型到另一种c++的隐式转换【英文标题】:implicitconversionofvectorfromonetypetoanotherc++【发布时间】:2015-05-2813:46:03【问题描述】:是否可以隐式将一种类型的向量转换为另一种类型?即让这段代码工作的某种方法(显... 查看详情

不允许从数据类型 nvarchar 到 varbinary(max) 的隐式转换

】不允许从数据类型nvarchar到varbinary(max)的隐式转换【英文标题】:Implicitconversionfromdatatypenvarchartovarbinary(max)isnotallowed【发布时间】:2011-09-0619:21:55【问题描述】:我从下面的代码中收到以下错误:。使用CONVERT函数运行此查询。p... 查看详情

opencv中operator的隐式类型转换(代码片段)

c++operator操作符的两种用法重载和隐式类型转换今天学习OpenCV源码的时候碰到这种写法:template<typename_Tp>operatorstd::vector<_Tp>()const;template<typename_Tp,intn>operatorVec<_Tp,n>()const;template<typename_ 查看详情

javascript数据类型的隐式转换(代码片段)

隐式转换(1)字符串连接:运算符+表示加法运算,JavaScript将把数字转换为字符串,再进行拼接。varres=44+"55";console.log(res);//4455(2)算术运算符(++–-*/%)或者比较运算符(><>=<&# 查看详情

带你玩转javascript中的隐式强制类型转换

...能一般人会想,不就是后者除了比较值相等之外还会比较类型是否相等嘛,有什么好问的,谁不知道?!但是这样说还不够准确,两者的真正区别其实是==在比较的时候允许做强制类型转换,而===不允许。好了终于引出了今天的... 查看详情

不允许从数据类型 nvarchar 到 varbinary(max) 的隐式转换

】不允许从数据类型nvarchar到varbinary(max)的隐式转换【英文标题】:Implicitconversionfromdatatypenvarchartovarbinary(max)isnotallowed【发布时间】:2012-07-1010:58:55【问题描述】:当我尝试将DBNull.Value插入nullablevarbinary(max)字段时,出现此异常:... 查看详情

在构造 std::variant 时禁用从指针类型到 bool 的隐式转换的最佳方法是啥?

】在构造std::variant时禁用从指针类型到bool的隐式转换的最佳方法是啥?【英文标题】:Whatisthebestwaytodisableimplicitconversionfrompointertypestoboolwhenconstructinganstd::variant?在构造std::variant时禁用从指针类型到bool的隐式转换的最佳方法是什... 查看详情

DateTime 等类型的隐式运算符,没有 ToShortDateString() 等日期时间函数

】DateTime等类型的隐式运算符,没有ToShortDateString()等日期时间函数【英文标题】:implicitoperatorontypeslikeDateTimewithoutdatetime-functionslikeToShortDateString()【发布时间】:2013-07-0309:08:43【问题描述】:我想使用带有隐式运算符的泛型类。... 查看详情