用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取

这篇具有很好参考价值的文章主要介绍了用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本节已经涉及Rust学习曲线上的一个大坑:泛型和特性了,属于语言的深水区,如果初学者,建议看一眼知道有这个功能即可。

如果我们立足于功能实现,那么做到像上一节那样就可以了,从原理上来说,每个函数满足唯一的功能,是一种好的设计,软件工程里面“高内聚低耦合”是有利于系统的独立性的。

但是在调用的时候,就需要有一点的心智了,例如我们要读取点线面三种不同的shapefile,就要记住三种不同的函数名和三种不同的绘图要素构建程序,那也太麻烦了,有没有一种方法,让我们调用一种方法,根据不同的参数类型自动适配不同的处理逻辑呢?

如果你是学Python/Java/JavaScript这样的高级语言的同学,你肯定已经有了自己的实现方法,例如Python/Javascript作为动态类型的语言,可以只写一个入口函数,然后根据函数的输入参数自动去选择不同的分支来处理。

而Java也有同名方法覆盖,利用不同的函数签名(参数类型)来解决用同名函数实现不同的逻辑流程。

而C++则是可以用泛型和函数重载来实现这个功能。

那么在Rust里面如何解决呢?

  • 首先,Rust不支持函数签名的类型推断。所有函数签名的类型必须写清楚,这就杜绝了我们用动态类型的语言那样根据输入的参数来匹配。
  • 第二,Rust也不(直接)支持函数重载,为什么是不直接支持呢,因为可以通过泛型和特性来实现函数重载,也就是我们今天要做的内容。

老规矩,先看结果:

用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取,rust,开发语言,后端

用同名的一个方法,实现对于三种不同的shapefile读取,并且获取三种不同的返回类型值,那么这是这么实现的呢?

先看代码:

架构定义

  • 首先定义了一个结构体,这个空结构体的作用类似于Java里面的class。
  • 然后定义了一个特性(trait),特性这个东西,在Rust中,类似于Java里面的接口,或者C++里面的虚函数,但是与接口和虚函数不同的时候,特性可以直接在里面写实现,也可以留空,如果你是学Java的,你把下面的代码理解为定义了一个接口,并且定义了一个实现接口的工厂方法即可。
  • 在这里的特性中,我们定义一个泛型T,然后定义了一个方法,就叫做read_shp,输入产生就是一个shapefile的路径,返回值是一个T ,这个T就是Rust中的泛型,即代表一切可能的类型。
    • 如果是没有接触过泛型的同学,可能会问,他既然代表一切类型,那么你不是说了Rust是类型严格的语言么?那系统编译器怎么知道,这个T到底是哪种类型呢?继续往下看
pub struct shp;
pub trait ReadShapfile<T> {
    fn read_shp(shp_path:&str) -> T;
}

然后我们开始写针对不同类型的shapefile的实现,实现如下:

//实现1:读取polygon类型的shapefile,通过返回值来匹配。
impl ReadShapfile<Vec<Polygon>> for shp{
    fn read_shp(shp_path:&str) -> Vec<Polygon>{
        let shp_read = shapefile::read_as::<_,
        shapefile::Polygon, shapefile::dbase::Record>(shp_path)
        .expect(&format!("Could not open polygon-shapefile, error: {}", shp_path));

    let mut polygons:Vec<Polygon> = Vec::new();
    for (polygon, polygon_record) in shp_read {
        let geo_mpolygon: geo_types::MultiPolygon<f64> = polygon.into();
        for poly in geo_mpolygon.iter(){
            polygons.push(poly.to_owned());
        }
    }
    polygons
    }
}

//实现2:读取Polyline类型的shapefile,通过返回值来匹配。
impl ReadShapfile<Vec<LineString>> for shp{
    fn read_shp(shp_path:&str) -> Vec<LineString>{
        let shp_read = shapefile::read_as::<_,
            shapefile::Polyline, shapefile::dbase::Record>(shp_path)
        .expect(&format!("Could not open polyline-shapefile, error: {}", shp_path));

        let mut linestrings:Vec<LineString> = Vec::new();
        for (pline, pline_record) in shp_read {
            let geo_mline: geo_types::MultiLineString<f64> = pline.into();
            for line in geo_mline.iter(){
                linestrings.push(line.to_owned());
            }
        }
        linestrings
    }
}
//实现2:读取Point类型的shapefile,通过返回值来匹配。
impl ReadShapfile<Vec<Point>> for shp{
    fn read_shp(shp_path:&str) -> Vec<Point>{
        let shp_read = shapefile::read_as::<_,
            shapefile::Point, shapefile::dbase::Record>(shp_path)
        .expect(&format!("Could not open polyline-shapefile, error: {}", shp_path));

        let mut pnts:Vec<Point> = Vec::new();
        for (pnt, pnt_record) in shp_read {
            let geo_pnt: geo_types::Point<f64> = pnt.into();
            pnts.push(geo_pnt.to_owned());
        }
        pnts
    }
}

简要的解释一下:

  • 在Rust的语法中,impl 特性名称<返回值> for 结构名 这个语法,代表了具体的实现,而里面那个 <返回值> 部分,就是我们定义的泛型T,注意,T只是一个代称,习惯性用大写字母,你用ABCDEFG,或者abcdefg都是可以的。

  • 然后在这个实现里面,去写具体方法的read_shp的实现,写完之后,就可以通过在调用的时候,再指定返回类型,来适配具体调用哪个方法了。

看到这里,可能有同学又有问题了:

上一节,直接写多个方法,多实用啊,读polygon就是polygon方法,读point就是point方法,干净整洁又高效,干嘛搞这么麻烦?

用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取,rust,开发语言,后端

实际上两种方式,都是可以的,每个方法用独立名称进行调用,实际上是一种比较传统,但是很高效的方式(C语言里面写操作系统内核都是这样写的)。

而后面这种,则是现代编程架构里面推荐的,用同名函数,来减少调用者的心智负担,反正都是读取shapefile,我干嘛还要记那么多个函数名啊?为什么不能用一个函数就全部解决了呢?

用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取,rust,开发语言,后端

所以在软件开发中,同名函数,通过定义不同的返回值,或者输入值来区分的方式,叫做多态,而在Rust里面,多态又可以分为静态分发:即静态多态模式或者单一态模式;以及动态分发:即动态多态模式

这种所谓的静态动态,在Rust中,是针对编译而言的,静态即代码和方法,在被编译的时候,就已经决定了编译的结果,你的输入、输出、处理流程等,都在编译的时候被固定下来了。

这种也是函数式编程的核心思想:函数式编程强调:不可变性和纯函数,这意味着函数的输出只取决于它的输入,而不依赖于外部状态

动态则相反,在编译的时候,系统并不知道要输入的参数和输出的结果具体是什么类型,只有在运行的时候,根据输入的数据情况才知道。

一般来说,动态语言中的动,就是这种,通常解释性的语言,都是动态的,例如Python/Javascript等。

当然,Rust也是支持动态编译的,但是在使用动态编译的时候,需要有一系列的手续,这个我们以后再说。

从两种编译模式来看,静态模式的开销小,安全性高,但是灵活性比较差;反之,动态模式灵活性好,但是开销大,安全性和稳定性较差。

具体在开发过程中,用哪种模式,就仁者见仁智者见智了。

最后我们来画一个UML图,就很容易看出来这个架构的实现思路了:

用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取,rust,开发语言,后端文章来源地址https://www.toymoban.com/news/detail-823062.html

到了这里,关于用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据可视化】教程及案例

    数据可视化是将数据通过图形、图像等形式直观展现出来的技术,它可以帮助人们更好地理解数据背后的信息和趋势。以下是一些数据可视化的教程和案例资源,以及它们各自的特点和应用场景。 ### 教程资源 1. **Python数据可视化入门教程【3】**    - 这些教程通常从Python的数

    2024年04月16日
    浏览(31)
  • Python可视化学习——使用JSON进行数据转换、pyecharts模块调用以及可视化案例的介绍(可视化案例数据暂无),柱状图及动态柱状图的构建

    可视化效果一:2020年印美日新冠累计确诊人数 2020年是新冠疫情爆发的一年,随着疫情的爆发,国内外确诊人数成了大家关心的热点,相信大家都有看过类似的疫情报告.本案例对印度美国日本三个国家确诊人数的进行了可视化处理,形成了可视化的疫情确诊人数报告.  可视

    2024年02月01日
    浏览(78)
  • 第一阶段-第十一章 Python基础的综合案例(数据可视化-地图可视化)

      说明:该文章是学习 黑马程序员 在B站上分享的视频 黑马程序员python教程,8天python从入门到精通 而记录的笔记,笔记来源于本人。 若有侵权,请联系本人删除 。笔记难免可能出现错误或笔误,若读者发现笔记有错误,欢迎在评论里批评指正。此笔记对应的doc文件的百

    2024年02月16日
    浏览(50)
  • 第一阶段-第十章 Python基础的综合案例(数据可视化-折线图可视化)

      说明:该文章是学习 黑马程序员 在B站上分享的视频 黑马程序员python教程,8天python从入门到精通 而记录的笔记,笔记来源于本人。 若有侵权,请联系本人删除 。笔记难免可能出现错误或笔误,若读者发现笔记有错误,欢迎在评论里批评指正。此笔记对应的doc文件的百

    2024年02月16日
    浏览(47)
  • THREEJS 地图可视化案例分享

    个人练习学习案例,代码放在git了,需要的可以下载 threejs_map: threejs 地图可视化案例 效果预览

    2024年02月12日
    浏览(61)
  • Python综合案例-学生数据可视化

    近年来,数据分析和可视化已经成为了许多领域中的重要工具。在教育领域中,通过对学生的表现和行为进行数据分析和可视化,可以更好地了解学生的学习状态,发现问题、改进教学,并提高学生成绩。本文将介绍一个 Python 综合案例,使用 Pandas 和 Seaborn 库,对学生的数据

    2024年02月02日
    浏览(36)
  • python数据分析及可视化(十四)数据分析可视化练习-上市公司可视化数据分析、黑色星期五案例分析

    从中商情报网下载的数据,表格中会存在很多的问题,查看数据的信息有无缺失,然后做数据的清晰,有无重复值,异常数据,省份和城市的列名称和数据是不对照的,删除掉一些不需要的数据,省份不完整的数据,然后进行数据分析以及可视化,如上市公司中的行业Top5,用

    2024年02月03日
    浏览(53)
  • ChatGPT AIGC 制作大屏可视化分析案例

    商品    价格 p1    13 p2    41 p3    42 p4    53 p5    19 p6    28 p7    92 p8    62 城市     销量 北京    69 上海    13 南京    18 武汉    66 成都    70 你现在是一名非常专业的数据分析师,请结合上述数据完成下列几件事情 1:第一部分数据做柱形图表,第二部

    2024年02月07日
    浏览(50)
  • 数据分析案例-顾客购物数据可视化分析

      🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 1.项目背景 2.数据集介绍 3.技术工具 4.导入数据 5.数据可视化 5.1分析性别比例 5.2年龄

    2024年02月07日
    浏览(53)
  • 以超市数据微案例-fineBI可视化分析

    一、入门案例: 2.分析思路: 数据清晰界面中添加毛利额计算 **所以在新增步骤之后,必须点击保存并更新,否则可视化界面中无法使用最新的数据 4、数据可视化分析 1)销售额最高的十大商品种类 为1-8月超市数据,商品名称--添加过滤条件 2)不同类别产品的销售额占比

    2024年01月19日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包