今天我们提到了类型变量。但我不明白这意味着什么。我只能在wiki上找到一个解释,type variable
我理解数学中的解释,但仍然不知道编程。任何人都可以解释一下吗?
答案 0 :(得分:2)
嗯,这很容易。基本观察是我们不仅有基本类型,如Int和Bool和Char,还有其他类型的类型。
最简单的例子是列表。在类型安全的语言中,列表的所有元素必须具有相同的类型。这就是我们写的原因:
Important: make sure the Compute Engine API is enabled for your project on the
等等。这已经很好了,但还不够好。事实证明,除了元素类型之外,列表上的某些函数是完全相同的,并且元素类型在函数内部是无关紧要的。这是一个例子:
Haskell Java Explanation
[Int] List<Integer> list of integers
[Char] List<Character> list of characters
因此,下一步是从元素类型中抽象出来并说:
lengthIntList :: [Int] -> Int -- compute length of a list of int
lengthIntList [] = 0
lengthIntList (x:xs) = 1 + length xs
lengthCharList :: [Char] -> Int -- compute length of a list of char
lengthCharList [] = 0
lengthCharList (x:xs) = 1 + length xs
此处,length :: [a] -> Int -- length of a list, for all elemen types
length [] = 0
length (x:xs) = 1 + length xs
是一个类型变量,表示:对于所有类型,此函数a
会获取该类型的列表并返回length
。
答案 1 :(得分:2)
维基百科的例子可以像这样用Java编写
public static <T> T identity(T a) {
return a;
}
其中a
的类型绑定到类型参数T
。因此,当您使用Integer
调用身份函数时,您会返回Integer
,当您使用String
调用它时,您将获得String
。
一个非常常见的用法示例是相同类型的值的集合,如字符串列表:
List<String> as = new ArrayList<String>();
List
接口中的type参数绑定到String
,因此该列表的所有元素都必须是String
类型。
更新了代码段,感谢Elliott。
答案 2 :(得分:1)
类型变量是一种通过编写适用于多种不同类型值的单个函数/方法来获得多态性的方法。这是Haskell中的一个例子:
id :: forall a. a -> a
id x = x
类型签名中的a
是一个类型变量,正如forall
所暗示的那样,这个函数适用于所有&#34;不同种类。例如,您可以使用id
,就像它具有类型Int -> Int
一样,或者就像它具有类型Char -> Char
一样。
id (5 :: Int) = 5 :: Int
id 'a' = 'a'
如果id
被赋予了具体类型(意味着没有类型变量),例如id :: Int -> Int
,那么id 'a'
将是类型错误,因为'a'
&#39 ; s类型(Char
)与Int
不匹配。
通常,我们省略forall
(id :: a -> a
),因为它可以很容易地从类型变量的使用中推断出来,但它有助于理解实际发生的事情。
我不知道Java和Haskell一样多,但是Generics似乎是一种使用类型变量的方法,因此ArrayList<A>
表示适用于任何非基本类型{{1}的数组列表}}
答案 3 :(得分:1)
使用Type变量,您可以为非指定类型的事物(Numbers,Text,...)定义数据类型/容器。为了提供一个简单的例子,想象一下,你想要一个盒子,你可以放置任何你想要的东西。
这是Java中的一个例子(T是类型变量):
public class Box<T> {
private T thing;
public void putThing(T thing) {
this.thing = thing;
}
}
以下是Haskell中的一个示例(a是类型变量):
data Box a = PutThing a
另一个很好的例子是通用元组数据类型。
示例用例
注意,在这两种情况下,类型变量现在都是指定的类型。
爪哇:
Box<String> box = new Box<String>();
box.putThing("42");
Haskell(在ghci中):
:t (PutThing (42::Int))
(PutThing (42::Int)) :: Box Int