当前位置:首页 > 数码 > 泛型编程实战指南 (泛型编程的好处)

泛型编程实战指南 (泛型编程的好处)

admin8个月前 (04-14)数码35

当天,咱们要深化讨论中的一项初级个性:泛型编程。泛型编程不只是Rust弱小类型系统的关键局部,而且是实现代码复用和类型安保的基础。

泛型编程的基本概念

在Rust中,泛型准许咱们编写可以处置多种数据类型的代码,而无需对每种类型编写特定的代码。这提高了代码的灵敏性和重用性。

泛型在函数中的运行

泛型最经常出现的运行场景是在函数定义中。例如,你或者宿愿编写一个可以接受任何类型参数的函数。

fnprint_value<T:std::fmt::Debug>(value:T){println!("{:?}",value);}

在这个例子中,print_value函数接受一个类型为T的参数,其中T是泛型类型。这象征着此函数可以打印任何成功了std::fmt::Debugtrt的类型。

结构体和枚举中的泛型

泛型也可以用在结构体和枚举的定义中。例如,你可以定义一个泛型结构体Point,它可以用于任何类型的坐标。

structPoint<T>{x:T,y:T,}

相似地,枚举也可以是泛型的。Rust规范库中的Option<T>和Result<T,E>就是两个经常出现的例子。

Trait和泛型联合

在Rust中,trait可以用来解放泛型。这象征着你可以要求泛型类型成功某些特定的行为。

fncompare<T:PartialOrd>(a:T,b:T)->bool{a>b}

这里的compare函数要求类型T必定成功PartialOrdtrait,这是Rust中用于比拟操作的trait。

泛型的初级用法

泛型编程不只限于便捷的类型交流。它可以用于构建复杂的数据结构和算法,比如泛型数据结构(如树、图等)和泛型算法。

例如,你可以创立一个泛型树结构,它可以蕴含恣意类型的数据:

structTreeNode<T>{value:T,children:Vec<TreeNode<T>>,}

泛型和性能

在Rust中,泛型不会影响运转时性能。Rust编译器在编译时会对每个详细的类型实例化泛型代码,这个环节称为单态化(monomorphization)。这象征着经常使用泛型编写的代码和为每种类型手写的代码一样高效。

实战运行

在实践开发中,泛型编程能极大优化代码的可保养性和复用性。例如,你可以创立泛型库,提供通用的数据结构和算法,无需针对每种数据类型重写代码。这在开发大型软件名目时尤其有用,可以清楚缩小代码冗余和失误。

泛型编程的应战

虽然泛型编程极大地优化了Rust的灵敏性和表白力,但它也带来了一些应战。正确地经常使用泛型须要对Rust类型系统有深化的了解,尤其是在处置复杂的类型解放和生命周期疑问时。

论断

泛型编程是Rust高效编程的关键。经过泛型,可以编写既灵敏又类型安保的代码,同时提高代码重用性。关于任何Rust开发者来说,了解和把握泛型


泛型的编程语言

Framework 的泛型泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。 泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型及其方法的参数类型出现。 泛型方法可以将其类型参数用作其返回值的类型或者其某个形参的类型。 由于 Framework 泛型的类型参数之实际类型在运行时均不会被消除,运行速度会因为类型转换的次数减少而加快。 另外,使用 GetType 方法可於程序运行时得知泛型及其类型参数的实际类型,更可以运用反射编程。 允许对个别泛型的类型参数进行约束,包括以下几种形式(假设 C是泛型的类型参数, 是一般类、泛类,或是泛型的类型参数):T 是一个类。 T 是一个值类型。 T 具有无参数的公有建构方法。 T 实现接口 I 。 T 是 C ,或继承自 C 。 Java 的泛型Java 泛型的参数只可以代表类,不能代表个别对象。 由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。 Java 编译器在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而加快。 Java 允许对个别泛型的类型参数进行约束,包括以下两种形式(假设 T 是泛型的类型参数,C 是一般类、泛类,或是泛型的类型参数):T 实现接口 I 。 T 是 C ,或继承自 C 。 一个泛型类不能实现Throwable接口。 C++ 的泛型(模板)C++ 无法对泛型的类型参数进行约束。 在编译时,每个被使用的封闭泛型类型(即是所有泛型参数的实际类型都已被指明的泛型)都会有独立的编码产生,编译器会在此时确保类型安全性。 可是如果泛型要运用其泛型参数的某成员,而该泛型参数又不包含该成员的时候,编译器所产生的错误信息会看似与实际问题无关,增加出错的难度。

泛型编程的简介

泛型编程的好处

泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。 STL以迭代器 (Iterators)和容器(Containers)为基础,是一种泛型算法(Generic Algorithms)库,容器的存在使这些算法有东西可以操作。 STL包含各种泛型算法(algorithms)、泛型迭代器(iterators)、泛型容器(containers)以及函数对象(function objects)。 STL并非只是一些有用组件的集合,它是描述软件组件抽象需求条件的一个正规而有条理的架构。 泛型的第一个好处是编译时的严格类型检查。 这是集合框架最重要的特点。 此外,泛型消除了绝大多数的类型转换。 如果没有泛型,当你使用集合框架时,你不得不进行类型转换。 关于泛型的理解可以总结下面的一句话,它是把数据类型作为一种参数传递进来。 泛型编程(Generic Programming)最初提出时的动机很简单直接:发明一种语言机制,能够帮助实现一个通用的标准容器库。 所谓通用的标准容器库,就是要能够做到,比如用一个List类存放所有可能类型的对象,这样的事情;熟悉一些其它面向对象的语言的人应该知道,如Java里面这是通过在List里面存放Object引用来实现的。 Java的单根继承在这里起到了关键的作用。 然而单根继承对C++这样的处在语言链底层的语言却是不能承受之重。 此外使用单根继承来实现通用容器也会带来效率和类型安全方面的问题,两者都与C++的理念不相吻合。 泛型编程最初诞生于C++中,由Alexander Stepanov[2]和David Musser[3]创立。 目的是为了实现C++的STL(标准模板库)。 其语言支持机制就是模板(Templates)。 模板的精神其实很简单:参数化类型。 换句话说,把一个原本特定于某个类型的算法或类当中的类型信息抽掉,抽出来做成模板参数T。 比如qsort泛化之后就变成了:template<class RandomAccessIterator, class Compare>void sort(RandomAccessIterator first, RandomAccessIterator last,Compare comp);其中first,last这一对迭代器代表一个前闭后开区间,迭代器和前闭后开区间都是STL的核心概念。 迭代器建模的是内建指针的接口(解引用、递增、递减等)、前闭后开区间是一个简单的数学概念,表示从first(含first)到last(不含last)的区间内的所有元素。 此外,comp是一个仿函数(functor)。 仿函数也是STL的核心概念,仿函数是建模的内建函数的接口,一个仿函数可以是一个内建的函数,也可以是一个重载了operator()的类对象,只要是支持函数调用的语法形式就可成为一个仿函数。 通过操作符重载,C++允许了自定义类型具有跟内建类型同样的使用接口;又通过模板这样的参数化类型机制,C++允许了一个算法或类定义,能够利用这样的接口一致性来对自身进行泛化。 例如,一个原本操作内建指针的算法,被泛化为操纵一切迭代器的算法。 一个原本使用内建函数指针的算法,被泛化为能够接受一切重载了函数调用操作符(operator())的类对象的算法。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: 泛型编程