news 2026/10/28 18:36:18

Fortran: 实现注册模式(Registry Pattern)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Fortran: 实现注册模式(Registry Pattern)

文章目录

      • ✅ 核心思想
      • 📌 示例:注册名字 → 对象映射
      • 🧪 使用示例
      • 🔍 说明与扩展建议
      • ✅ 总结

在 Fortran(特别是 Fortran 2003 及以后支持面向对象特性的版本)中,虽然没有像 C++ 或 Python 那样原生的“注册模式”(Registry Pattern)语法糖,但可以借助派生类型(derived types)、指针(pointers)或可分配变量(allocatable components)来实现类似功能:将一个对象“注册”到另一个对象中,并支持查询和变更。

Design patterns
https://github.com/farhanjk/FortranPatterns

下面是一个典型的实现思路和示例代码:


✅ 核心思想

  • 使用一个容器类型(如Registry)来保存一组被注册的对象(通过指针或 allocatable 组件)。
  • 提供register、lookup、update等过程(即方法)。
  • 利用 Fortran 的类型绑定过程(type-bound procedures)实现面向对象风格。

📌 示例:注册名字 → 对象映射

module registry_mod implicit none private public :: Item, Registry type :: Item integer :: value = 0 contains procedure :: set_value procedure :: get_value end type Item type :: Registry private type(Item), pointer :: items(:) => null() character(len=:), allocatable :: keys(:) integer :: n = 0 integer, parameter :: initial_capacity = 10 contains procedure :: register_item procedure :: lookup_item procedure :: update_item final :: finalize_registry end type Registry contains subroutine set_value(this, val) class(Item), intent(inout) :: this integer, intent(in) :: val this%value = val end subroutine set_value function get_value(this) result(val) class(Item), intent(in) :: this integer :: val val = this%value end function get_value subroutine register_item(this, key, item) class(Registry), intent(inout) :: this character(len=*), intent(in) :: key type(Item), intent(in) :: item integer :: i ! 检查是否已存在 do i = 1, this%n if (this%keys(i) == key) then error stop 'Key already exists: ' // trim(key) end if end do ! 扩容 if (.not. associated(this%items)) then allocate(this%items(this%initial_capacity)) allocate(this%keys(this%initial_capacity), source='') else if (this%n >= size(this%items)) then call resize(this) end if this%n = this%n + 1 this%keys(this%n) = key this%items(this%n) = item end subroutine register_item function lookup_item(this, key) result(item_ptr) class(Registry), intent(in) :: this character(len=*), intent(in) :: key type(Item), pointer :: item_ptr integer :: i item_ptr => null() do i = 1, this%n if (this%keys(i) == key) then item_ptr => this%items(i) return end if end do end function lookup_item subroutine update_item(this, key, new_item) class(Registry), intent(inout) :: this character(len=*), intent(in) :: key type(Item), intent(in) :: new_item integer :: i do i = 1, this%n if (this%keys(i) == key) then this%items(i) = new_item return end if end do error stop 'Key not found for update: ' // trim(key) end subroutine update_item subroutine resize(this) class(Registry), intent(inout) :: this type(Item), allocatable :: temp_items(:) character(len=:), allocatable :: temp_keys(:) integer :: old_size, new_size old_size = size(this%items) new_size = old_size * 2 allocate(temp_items(new_size)) temp_items(1:old_size) = this%items deallocate(this%items) this%items => temp_items allocate(temp_keys(new_size), source='') temp_keys(1:old_size) = this%keys deallocate(this%keys) this%keys = temp_keys end subroutine resize subroutine finalize_registry(this) type(Registry), intent(inout) :: this if (associated(this%items)) deallocate(this%items) if (allocated(this%keys)) deallocate(this%keys) end subroutine finalize_registry end module registry_mod

🧪 使用示例

program test_registry use registry_mod implicit none type(Registry) :: reg type(Item), pointer :: p => null() type(Item) :: tmp ! 注册 call tmp%set_value(42) call reg%register_item('answer', tmp) ! 查询 p => reg%lookup_item('answer') if (associated(p)) then print *, 'Found value:', p%get_value() end if ! 更新 call tmp%set_value(100) call reg%update_item('answer', tmp) p => reg%lookup_item('answer') if (associated(p)) then print *, 'Updated value:', p%get_value() end if end program test_registry

🔍 说明与扩展建议

  • 键值对:当前使用character作为 key,也可替换为整数 ID 或其他类型。
  • 指针 vs allocatable:这里items用指针数组便于返回引用;若只存副本,可用allocatable。
  • 线程安全:Fortran 本身不提供线程安全机制,如需多线程需加锁(例如通过 OpenMP critical)。
  • 泛型支持:Fortran 不支持模板,若需注册不同类型,可考虑:
    • 使用class(*)+select type(但复杂)
    • 为每种类型写专用 Registry
    • 或使用预处理器(如 fypp)生成代码

✅ 总结

Fortran 2003+ 完全可以实现注册模式,核心是:

  • 用派生类型封装注册表
  • 用指针/数组存储对象
  • 提供注册、查找、更新接口
  • 利用 finalizer 自动清理资源
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 5:47:01

OCR识别质量评估:CRNN模型的评价指标解析

OCR识别质量评估:CRNN模型的评价指标解析 📖 引言:OCR文字识别的技术价值与挑战 光学字符识别(Optical Character Recognition, OCR)是将图像中的文字内容转化为可编辑文本的关键技术,广泛应用于文档数字化…

作者头像 李华
网站建设 2026/10/27 11:39:09

海尔智能家居集成完整配置指南

海尔智能家居集成完整配置指南 【免费下载链接】haier 项目地址: https://gitcode.com/gh_mirrors/ha/haier 海尔Haier智能家居集成是HomeAssistant中功能最全面的海尔设备连接解决方案,能够将您家中的所有海尔智家设备无缝接入智能家居系统。这个强大的集成…

作者头像 李华
网站建设 2026/10/28 10:35:47

高并发场景应对:OCR服务负载均衡配置方案

高并发场景应对:OCR服务负载均衡配置方案 📖 项目简介与技术背景 随着数字化进程的加速,OCR(光学字符识别) 技术在发票识别、文档电子化、智能客服等场景中扮演着越来越关键的角色。尤其是在企业级应用中,单…

作者头像 李华
网站建设 2026/10/27 0:47:03

新手必备:5分钟学会用gifski制作高清GIF动画的完整教程

新手必备:5分钟学会用gifski制作高清GIF动画的完整教程 【免费下载链接】gifski GIF encoder based on libimagequant (pngquant). Squeezes maximum possible quality from the awful GIF format. 项目地址: https://gitcode.com/gh_mirrors/gif/gifski 还在…

作者头像 李华
网站建设 2026/10/23 14:17:41

告别混乱:脚本窗口管理效率提升300%的方案

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 实现一个高效的窗口管理器类,具有以下功能:1. 使用WeakMap自动跟踪所有打开的窗口 2. 提供按条件过滤关闭窗口的能力(如只关闭特定域名窗口&…

作者头像 李华
网站建设 2026/10/27 21:32:26

零基础教程:5分钟学会CAD批量打印插件安装使用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 设计一个极简版的CAD批量打印插件,要求:1.三步完成安装(下载-运行-重启CAD);2.直观的拖放式操作界面;3.内置…

作者头像 李华