V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  xiuy  ›  全部回复第 1 页 / 共 1 页
回复总数  4
79 天前
回复了 VERT1GO 创建的主题 职场话题 编译器开发相关的工作值得入坑吗?
是 HDC 刚发布的语言那个团队吗
2020-11-23 14:35:58 +08:00
回复了 GTD 创建的主题 程序员 现在学习计算机,走哪个领域会比较有前途?
来这里问这个没什么帮助的
2020-11-16 02:21:24 +08:00
回复了 JasonLaw 创建的主题 程序员 分享一个关于协变、逆变、不变的优秀回答
这个回答不能称得上是对协变、逆变的解释,只是针对这个问题来说,这个答案还是讲得挺明白的。

要理解 covariant 和 contravariant 的话,首先要明白的是 subtype 的基础概念。

> Type S is a subtype of a type T, written S <: T, if an expression of type S can be used in any context that expects an element of type T.

举个例子的话,就是任何需要一个 Animal 的地方,都可以放进去一个 Dog,那么 Dog <: Animal 。(看着很像 Inheritance 是因为大多数的程序语言把 Inheritance 和 Subtyping 混在一起了)

而协变与逆变其实与 Function Subtyping 有关。(也就是 #2 中的「只有将类型作为参量(包括泛型)才有协变逆变之说」)

Function Subtyping 的定义是这样婶儿滴:(S' -> T') <: (S -> T) if S <: S' and T' <: T.

协变和逆变就是从这里来的,这里的 S <: S' 就是逆变,而 T' <: T 是协变。

说直白一点就是 T' <: T 是顺着 (S' -> T') <: (S -> T) 来的,而 S <: S' 这个关系要求逆过来。

再叨叨多一点,这个定义其实挺反直觉的,如果要 (S' -> T') <: (S -> T) 的话,我们可能以为条件应该是 S' <: S 和 T' <: T 。这时候需要回头在看一下 subtypes 的定义:*S <: T, if an expression of type S can be used in any context that expects an element of type T*. **当 T 变成了 f, 问题就转为寻找一个能代替 f 的 f'。**

这个图示非常有助于理解:

![Untitled.png]( https://i.loli.net/2020/11/16/Hy3fKGed5gYI6uv.png)

S 需要是 S' 的 subtype ( S <: S'),任何原来的输入才能放得进去;而 T' 必须是 T 的 subtype,任何出来的 T' 才能被视作 T 。

对于有范型的类来说,我觉得 [Scala 这个文档]( https://docs.scala-lang.org/zh-cn/tour/variances.html) 讲得挺好的,不会 Scala 也能看懂。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5652 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 15ms · UTC 02:56 · PVG 10:56 · LAX 18:56 · JFK 21:56
Developed with CodeLauncher
♥ Do have faith in what you're doing.