首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在强制中将“Measurement<UnitLength>”类型的值转换为“Measurement<Dimension>”类型

无法在强制中将“Measurement<UnitLength>”类型的值转换为“Measurement<Dimension>”类型
EN

Stack Overflow用户
提问于 2022-02-02 12:14:43
回答 3查看 212关注 0票数 0

我有结构向量:

代码语言:javascript
复制
struct Vector{
var X : Measurement<Dimension>
var Y : Measurement<Dimension>
var Z : Measurement<Dimension>
...

我创建了新的对象,例如:

代码语言:javascript
复制
let test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>
var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))

一切都很好。但是,如果尝试使用其他类中的变量,则会出现以下错误:“无法将类型‘测量’的值转换为强制情况下的‘测量’类型”。

代码语言:javascript
复制
final class SettingsManager{
  ...
 var test  = Measurement(value: 1.5, unit: UnitLength.inches)
  ...  }
class Calculator {
 ...
 let test = SettingsManager.shared.test as Measurement<Dimension>
 var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))

我试过“作为!”并得到了

代码语言:javascript
复制
Cast from 'Measurement<UnitLength>' 
to unrelated type 'Measurement<Dimension>' 
always fails

在这个类中声明的相同变量可以正常工作,就像我在上面展示的那样。我做错了什么?

EN

回答 3

Stack Overflow用户

发布于 2022-02-02 12:36:18

Measurement<UnitLength>不是Measurement<Dimension>的一种。这些都是不相关的类型。它只在这里起作用:

代码语言:javascript
复制
let test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>
var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))

因为这里的Measurement(...)调用实际上是在创建Measurement<Dimension>,因为这正是调用站点所期望的。as Measurement<Dimension>告诉它您需要一个Measurement<Dimension>,而xz的参数类型也是Measurement<Dimension>。类型推断算法足够聪明,可以看出您也必须是指Measurement<Dimension>(...)

Measurement<Dimension>.init将一个Dimension作为它的第二个参数,而UnitLength是该参数的一个子类型,因此没有问题。

另一方面,在SettingsManager中,您这样声明test

代码语言:javascript
复制
var test = Measurement(value: 1.5, unit: UnitLength.inches)

这里没有提到Measurement<Dimension>,所以类型推断算法只使用第二个参数来推断您必须指的是Measurement<UnitLength>,所以test的类型是Measurement<UnitLength>

如果您只是添加as Measurement<Dimension>

代码语言:javascript
复制
var test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>

应该管用的。

然而,如果向量的所有三个组件都有相同类型的单位,难道不是更有意义吗?

代码语言:javascript
复制
struct Vector<T: Dimension>{
    var X : Measurement<T>
    var Y : Measurement<T>
    var Z : Measurement<T>
}
票数 3
EN

Stack Overflow用户

发布于 2022-02-02 13:57:58

这只是为了解决为什么这是合法的问题:

代码语言:javascript
复制
let test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>
var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))

这甚至不应该是一个问题,这只是正常的替代原则。让我们用一种简单的方式来表达它。如果你不投呢?

代码语言:javascript
复制
let test = Measurement(value: 1.5, unit: UnitLength.inches)

然后test被推断为Measurement<UnitLength>。现在让我们开始:

代码语言:javascript
复制
let test: Measurement<Dimension> = Measurement(value: 1.5, unit: UnitLength.inches)

这是合法的。为什么?这并不是因为Measurement<UnitLength>Measurement<Dimension>的一个子类型。不是的!这是因为UnitLength是维度的一个子类型。就好像你说过

代码语言:javascript
复制
let test = Measurement(value: 1.5, unit: UnitLength.inches as Dimension)

你看到了吗?实际上,您并没有将Measurement<UnitLength>转换为Measurement<Dimension>;这是不可能的。您将UnitLength转换到维度,这是完全可能的。这和你说的没什么不同

代码语言:javascript
复制
let test2: Dimension = UnitLength.inches

您总是可以在需要超级类型的地方替换子类型。最初问题的难点在于Measurement<UnitLength>不是Measurement<Dimension>的子类型(因为Swift泛型不会在参数化类型上自动协变)。

票数 1
EN

Stack Overflow用户

发布于 2022-02-02 12:31:41

当您在test中声明SettingsManager变量时,您没有显式地提到一个类型。因此,斯威夫特的类型推理算法决定了变量的类型取决于Measurement(...)中的第二个参数。

在本例中,test具有Measurement<UnitLength>类型。如果您使用传递的UnitArea.acres作为第二个参数,您的变量将具有Measurement<UnitArea>类型。不是Measurement<Dimension>

如果您首先以Measurement<Dimension>的形式显式地提到该类型,它将解决这个问题。

代码语言:javascript
复制
var test : Measurement<Dimension>  = Measurement(value: 1.5, unit: UnitLength.inches)

现在让我们检查一下为什么你的铸造失败。您可以将类型转换为它的子类型或超级类型。UnitLengthDimension的一个子类型。这样你就可以在他们中间投了。

但是Measurement<UnitLength>而不是,是Measurement<Dimension>的一个子类型。为什么?

原因很简单。泛型是不变的。这意味着,即使泛型类型包装了一个子类型,它也不会使它成为包装其超类的泛型的子类型。

有关上述段落的更多说明,请阅读

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70955451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档