什么是元编程?

C 语言的元编程(Metaprogramming in C) C语言通过预处理器宏实现有限的元编程能力,包括宏定义、字符串化/连接、可变参数宏、X-Macro技术和泛型模拟等。尽管存在无法递归、类型不安全等局限性,但在生成重复代码、实现轻量级泛型容器等场景中仍具实用价值。现代C11标准引入的_Generic关键字显著提升了类型分支处理能力。使用时需权衡功能与可维护性,避免过度复杂的宏技巧。 阅读详情

临下班的紧急任务

时钟指向6点半,张大胖今天不太忙,想着今天终于可以早点儿下班了。

收拾好东西准备离开的时候,领导布置了一个新任务,张大胖很无奈,哀叹一声,老老实实地坐下来。

新任务看起来非常简单:从一个CSV文件中读取数据,形成Java对象,然后对外提供一个API,让别人调用。

这个CSV文件叫做employee.csv, 张大胖打开这个CSV文件,里边的内容一看就懂。

name,age,level

Andy,25,B7

Joe, 22, B6

张大胖的API就需要返回一个List<Employee>,很自然,Employee类长这个样子:

public class Employee{
    private String name;
    private String age;
    private String level;
    ......
}

class中的每个字段和csv文件的“表头”的“列名”保持一致。

这样简单的任务对张大胖来说是小菜一碟,他写了一个EmployeeParser,专门解析CSV文件,形成Employee对象,半个小时不到就收工了,赶紧下班!

640?wx_fmt=png

640?wx_fmt=gif

还没来得及溜走,又被领导叫住了:“大胖,那个CSV文件新加了一个字段,叫做salary ,快把你的程序改一下啊!”

name,age,level,salary

Andy,25,B7,3000

Joe, 22, B6,2500

张大胖极不情愿地坐下来,给Employee类增加了一个salary的字段,又修改了EmployeeParser类,增加对这个字段的解析。

然后又听到领导在喊:“又加了一个字段,叫做tax !”

没辙,继续修改Employee类和EmployeeParser类吧。 这一次修改完,领导终于放他走了。

模板:用程序来生成程序

等了两趟车,终于在西二旗挤上了13号线,张大胖心里一直在想:明天保不齐还要增加字段,这真是让人厌烦的重复劳动啊。大家都说,Don't repeat yourself, 我这怎么才能减少重复呢?

关键点就在于,那个Java类的字段要和CSV的表头的列名做对应,CSV变化了,Java类的字段以及解析的方法都要做相应得修改才可以。

对了,能不能根据CSV的列名自动地生成那个Employee类啊,这样问题不就解决了吗? CSV变化, Employee类跟着变化,多好!

CSV的“列名”经过读取,可以变成一个Java 的List ,例如["name","age","level"], 如何写一段代码,把这个List变成一个Employee Class呢?

张大胖聚精会神,在地铁上想了一路,完全无视地铁上那拥挤的人群和污浊的空气。

快要下车时,他灵机一动,可以用模板技术嘛,比如velocity模板,定义一个employee.vm :

public class Employee{    
    #foreach ($field in $headers)
        private String $field;         
    #end    
    ##其他代码略
}

然后再写一个代码生成器,读取employee.csv的“表头”,形成List,把List传递给这个employee.vm模板,就可以输出Java类了:

640?wx_fmt=png

写成具体的代码就是这个样子:


VelocityEngine ve = new VelocityEngine();

...初始化引擎的代码略...

Template template = ve.getTemplate("employee.vm");   

VelocityContext context = new VelocityContext();

List&lt;String&gt; headers = readCSVHeaders();

context.put("headers",headers);

Writer writer = new PrintWriter(new FileOutputStream(
                new File("C:\\Employee.java")));           

//把headers变量传递给模板
template.merge(context, writer);
writer.flush();    

(友情提示:可左右滑动)

(码农翻身注:这里做了简化只关注了Empployee的字段,还需要处理getter/setter方法,尤其是也需要通过模板的方法生成EmployeeParser,用来形成Employee对象。此外还有数据类型的问题。)

在小区对面的田老师红烧肉吃了一份盖饭以后,张大胖立刻投入到程序的编写中来,一边写一边想:我这是用程序来生成程序啊!

元编程

第二天,领导果然要加新的字段了,张大胖心中暗自佩服自己的自知之明,调出昨晚写的“宝贝”执行了一下,不到一秒钟,新的Employee和EmployeeParser就生成了。

下午的时候,张大胖洋洋得意地给Bill展示自己的工作成果,Bill说:“不错啊,都开始元编程了!”

“元编程?”

“对啊,你不是用程序来生成程序嘛,这就是一种元编程。”

张大胖没想到的工作居然就是高大上的“元编程”,更高兴了。

“还有,如果把CSV文件看成数据库的表,代码生成器自动生成的EmployeeParser不就相当于DAO吗?Employeeb 不就是和数据表映射的Domain对象吗? 你的代码实现了Object-relational mapping !”

就是啊,我怎么没想到,虽然距离真正的O/R Mapping还很远,但思想是一致的,大神就是厉害,看透了本质,张大胖暗想。

可是Bill很快给它泼了一盆冷水:“不过这种用模板生成的方式还是有些‘低级’,每次CSV文件有变化,都需要运行一下代码生成器才可以。”

“那怎么办?”

“其实吧,这个Employee的类没有必要在编译期存在,如果能在运行时动态地生成就行了。”

运行期动态生成? 张大胖有点懵。

“对于Java语言来说,运行期在内存中动态生成一个Class,还是有难度的,你需要透彻理解Java Class的文件格式,还需要在底层需要用ASM这样的东西去操作Java字节码。”

“文件格式和字节码?就是那些0xCAFEBABE,iload ,iadd, putfield,invokespecial ? ”  张大胖看过虚拟机的书,知道有很多字节码,但是操作它们形成符合要求的类,实在是难以想象。

Bill 笑道:“你可以用动态语言,比如Ruby,元编程很强大,实现你这个功能简直是小菜一碟。”

Bill很快就写出了一段代码:

#在内存中创建一个名称为Employee的类
klass = Object.const_set("Employee", Class.new) 

names= ...读取csv文件第一行,形成数组,如 ["name","age","level"]...

#对这个内存中的类进行"手术"
klass.class_eval do
    #现在 name,age,level...变成了这个Employee类的字段!
    attr_accessor *names    
    #再定义一个Employee类的构造函数    
    define_method(:initialize) do |*values|  
        names.each_with_index do |name, i|  
        instance_variable_set("@" + name, values[i])  
    end
    end 
end 

(友情提示:可左右滑动)

张大胖没有学过Ruby , 看到这里更懵了。

Bill看到张大胖发呆的样子,说道:”经过上述处理,内存中创建了一个类,如果把它的源码展示一下,你就明白了。”

#动态生成的类
class Employee
  #动态生成的属性,类似与java的getter方法
  def name
    @name
  end
  #动态生成的属性,类似java的setter方法
  def name=(str)
    @name = str
  end
  def age
    @age
  end
  def age=(str)
    @age = str
  end
  def level
    @level
  end
  def level=(str)
    @level = str
  end
  #动态生成的构造函数
  def initialize(*values)
      @name = values[0]
      @age = values[1]
      @level = values[2]
  end
end
#一个使用Employee类的例子
p = Employee.new("andy","22","B6")

(友情提示:可左右滑动)

(码农翻身注:对CSV文件内容的读取没有包括在其中。)

张大胖明白了,这个类是由数据驱动,动态生成的,CSV的header 中有多少字段,这个类就会生成多少个属性。

和自己的代码生成器比较了一下,Ruby写的这段代码更加精炼,不需要模板,没有所谓代码生成器,或者说,代码生成器和生成的类已经合二为一了。

即使是CSV文件发生了变化,也不需要额外运行代码生成器,只需要执行那段Ruby代码就行。

640?wx_fmt=png640?wx_fmt=gif

Bill问道:“怎么样,元编程不错吧?”

张大胖说道:“嗯, 这Ruby的元编程能力很强大啊,可惜的是,我们的项目都是Java的,这动态的脚本语言Ruby没法直接使用,如果是微服务,对外提供的是HTTP的API,我可以学学Ruby,单独写个Ruby项目。”

Bill说:“其实吧,编程语言中,元编程能力最强大的还属LISP,在LISP当中,程序和数据的表现形式是一致的,造就了它无以伦比的元编程能力,LISP程序可以像操作数据一样操作代码。 有人甚至说,LISP根本不是编程语言,它是编程元语言,专门为了生成程序而生。”

张大胖听得云里雾里,黯然道:“不知道你在说什么,太抽象了!等我学学LISP以后再回来和你讨论吧。”

(完)

码农翻身,用故事讲解技术本质, 更多精彩文章,请移步《码农翻身三年文章精华》

什么是元编程(meta-promgramming)? 抠定义的话是这样吧。除非程序的运行期的输入数据会被直接或间接转化成代码,否则元编程不会给程序带来新的逻辑(信息论原理),此时它本质上是一种(让程序员自我感觉良好的)手工压缩源代码技术。换言之,一种语言本来做不到的事情,通过你编程来修改它,使得它可以做到了,这就是元编程。泛泛来说,只要是与编程相关的编程就算是 meta-programming 了——比如,若编程甲可以输出 A - Z,那么写程序甲算「编程」;相对于新创造的领域专用语言DSL来说, Ruby语言就成为其的元语言,所以叫做元编程。 阅读详情

相关推荐

python元编程详解

一、元编程的概念 元编程依赖于python的一个叫做元类的概念。元类就是当你的某段代码在被执行的过程中,另外一段代码同时在被执行。维基百科上说的很好,在面向对象编程中,元类的实例还是类。 当我们定义一个类时,该类的对象都是由这个类来创建。但是类本身呢?类又是由什么来创建的呢? 这个问题就引申出元类的概念了,元类可以为其他类定义属性。举个例子,下面这段代码为每个类添加了一个hello属性,而这些类都是由定义的元类创建。也就是说,这些类都会有一个hello的属性,并不需要他们自己去定义。 运行上面的代码,得到

2622

Python元编程:代码的幕后之舞

在Python的编程世界中,元编程犹如一场神奇的幕后之舞,让程序员能够在代码执行的过程中实现各种奇妙的操作。本文将深入探讨两个核心方面:动态属性和方法的魔法变形,以及使用元类的创造力,并讨论它们在实际应用中的优势和注意事项。

theskylife的博客 1396

浅谈C++元编程

随着 C++ 11/14/17 标准的不断更新,C++ 语言得到了极大的完善和补充。元编程作为一种新兴的编程方式,受到了越来越多的广泛关注。结合已有文献和个人实践,对有关 C++ 元编程进行了系统的分析。首先介绍了 C++ 元编程中的相关概念和背景,然后利用科学的方法分析了元编程的 演算规则、基本应用 和实践过程中的 主要难点,最后提出了对 C++ 元编程发展的 展望。 1 引言 1.1 什么是元...

LU_ZHAO的博客 1760

ES6与元编程

ES6中的元编程 元编程概述 元编程是当你将程序的逻辑转向关注它自身(或者它的运行时环境)时进行的编程,要么为了调查它自己的结构,要么为了修改它。元编程的主要价值是扩展语言的普通机制来提供额外的能力。 元编程通常有两种方式起作用。一种方式是通过应用程序接口(API)来暴露运行时引擎的内部信息。...

chucaiju4190的博客 388

C++模板元编程详解

C++模板是支持泛型编程的重要特性,允许编写与类型无关的代码,提升代码复用性和灵活性。模板分为函数模板和类模板,分别用于生成通用函数和类。模板参数包括类型参数、非类型参数和模板模板参数。模板实例化是编译器根据具体类型生成代码的过程,而模板特化则允许为特定类型提供特殊实现。模板元编程(TMP)利用模板在编译时进行计算或生成代码,结合constexpr、SFINAE、类型萃取、可变参数模板等技术,实现编译期计算和类型操作。

weixin_43484713的博客 1844

.NET元编程英文版

.NET元编程英文版

浅谈 C++ 元编程

随着 C++ 11/14/17 标准的不断更新,C++ 语言得到了极大的完善和补充。元编程作为一种新兴的编程方式,受到了越来越多的广泛关注。结合已有文献和个人实践,对有关...

腾讯技术工程 5670

lemon:元编程语言

lemon:元编程语言

C++元编程

元编程:编写可以让编译系统生成新代码的代码,而新生成的代码,正式我们想要的代码。元编程的目的,用尽量少的付出,换取尽可能多的功能,“付出”可以用代码成本,维护成本之类的事情来衡量。c++元编程的特性之一就是编译期间执行用户自定义的运算。

flyingshineangel的专栏 657

xl:一种基于元编程和语法分析树重写的极简通用编程语言

XL-一种可扩展的语言 警告:XL正在开发中。 即使有些零碎已经发生了,XL目前也不适合进行任何严肃的编程。 下面给出的示例有时可能根本行不通。 令人痛苦地提醒人们,这项工作还远远没有完成,并且,谁知道,这是一个贡献的想法。 有关如何解决当前混乱的信息,请参见;有关预期工作的信息,请参见;有关编译器内部的快速概述,请参见。 XL是一种可扩展的编程语言,旨在轻松满足各种编程需求。 可扩展性意味着该语言旨在使程序员非常容易地适应该语言以适应其需求,例如通过添加新的编程结构。 在XL中,扩展语言是例行操作,就像在更传统的编程语言中添加函数或创建类一样。 作为对此大胆主张的验证,XL具有单个基本运

Python爬虫实战:从巨潮资讯网高效获取结构化JSON数据

在数据采集与处理领域,网络爬虫是实现自动化信息获取的核心技术。其基本原理是通过模拟浏览器行为,向目标服务器发送HTTP请求并解析响应内容,从而提取所需数据。相较于传统的网页解析,直接获取结构化数据(如JSON格式)能极大提升数据处理的效率与准确性,避免了复杂的HTML解析或PDF文本提取过程。这一技术价值在金融数据分析、市场研究、舆情监控等场景中尤为突出,能够快速构建高质量的数据集。本文以Python爬虫为例,聚焦于从巨潮资讯网这类官方信息披露平台,精准定位并抓取JSON格式的上市公司年报数据,详细阐述了接

weixin_29243279的博客 1419

C++模板元编程

        所谓的元编程就是编写直接生成或操纵程序的程序,C++模板为C++语言提供了元编程的能力。模板使 C++ 编程变得异常灵活,能实现很多高级动态语言才有的特性(语法上可能比较丑陋,一些历史原因见下文)。普通用户对 C++ 模板的使用可能不是很频繁,大致限于泛型编程,但一些系统级的代码,尤其是对通用性、性能要求极高的基础库(如 STL、Boost)几乎不可避免的都大量地使用 C++ 模板...

nbaDWde的博客 1万+

微信小程序云开发订单微信支付与小票和标签打印的完整高效流程

本片文章全文12000字,细致讲述从申请账户到小程序注册到打印机的选型最后到实现微信小程序云开发订单支付更新与小票,标签打印完整的高效流程。客户A在我们的点餐平台上点了一杯咖啡,所以客户要在选好后付款,在付款完成后商家的小票打印机和标签打印机打印出本订单的相关信息。

weixin_52312427的博客 3649

C++ 元编程

浅谈 C++ 元编程 随着 C++ 11/14/17 标准的不断更新,C++ 语言得到了极大的完善和补充。元编程作为一种新兴的编程方式,受到了越来越多的广泛关注。结合已有文献和个人实践,对有关 C++ 元编程进行了系统的分析。首先介绍了 C++ 元编程中的相关概念和背景,然后利用科学的方法分析了元编程的演算规则、基本应用和实践过程中的主要难点,最后提出了对 C++ 元编程发展的展望。 ...

cxu123321的博客 2257

数字孪生实战:如何用Blender+Unity快速搭建未来工厂3D模型(附资源包)

本文提供了一套利用Blender进行三维建模,再结合Unity构建虚拟仿真环境的实用方案,旨在帮助中小型制造企业低成本、高效率地搭建未来工厂数字孪生原型系统。文章详细介绍了从数据规划、模型优化到场景构建、逻辑仿真与数据对接的全流程,并附有资源包,助力技术团队快速实现从静态展示到动态交互的数字孪生应用。

weixin_29191669的博客 338

实战复盘:纷玩岛(Livelab)候补订单微信支付协议的逆向与复现

通过本次对纷玩岛候补支付接口的分析,我们实现了一个脱离 App UI 的轻量级支付发起器。这不仅验证了其API的设计逻辑(Standby -> PrePayInfo 分层设计),也为后续的自动化监控或辅助抢票工具提供了支付环节的技术验证。技术本无罪,关键在于如何使用。理解这些底层协议,有助于我们写出更健壮的代码,也能在遇到线上支付问题时快速定位是业务层(API)问题还是通道层(微信)问题。

猫敷雪 801

元编程(Metaprogramming)

元编程通过宏、模板元编程、反射和注解等技术,提供了强大的能力来生成和操作代码。这些技术使得程序能够更加灵活和动态地适应复杂需求,但同时也增加了代码的复杂性和维护成本。在使用这些技术时,开发者应权衡它们带来的灵活性与复杂性之间的平衡,确保代码的可读性和性能。元编程通过动态代码生成、代码自省和行为修改等能力,解决了许多编程中的复杂性问题。它使代码更具灵活性和通用性,减少了重复劳动,并提高了代码的表达能力和可扩展性。因此,元编程在构建复杂系统、通用框架以及动态可扩展软件时,发挥了至关重要的作用。

goTsHgo的博客 2106

用 OData V2 元数据驱动表格体验:SAP UI5 Smart Table 全面解析

摘要: Smart Table是SAPUI5中基于OData元数据自动生成表格的控件,支持个性化、排序、过滤等高级功能。文章从九个维度深入解析其工作机制:1)通过元数据和注解自动生成列;2)支持多种表格类型;3)关键属性的静态化特性;4)与其他智能控件的协同;5)导航属性和导出的处理;6)响应式设计;7)个性化配置;8)性能优化策略;9)端到端实现案例。Smart Table通过读取OData元数据自动完成表格渲染,大幅减少开发工作量,特别适合企业级应用开发场景。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 322

55 C++ 现代C++编程艺术4-元编程

C++元编程技术通过编译时计算优化程序性能,主要包括四种方法:1)模板元编程,利用递归模板特化实现编译期计算;2)constexpr元编程,通过constexpr函数和变量进行常量求值;3)宏元编程,使用预处理宏生成代码;4)C++20概念约束元编程,用concepts规范模板参数要求。这些技术能实现零开销抽象,提升代码效率和类型安全,但需权衡可读性与编译复杂度。典型应用包括数学计算、类型检查和代码生成等场景。

17208955的博客 2052

学Simulink——十二脉波整流电路(移相变压器)谐波抵消仿真

Y:Δ = 1:√3(若 DC 同压)— 此处同相电压故 220V(Y)=220V(Δ phase)Y(相电压=220V)、Δ(线电压=380V ⇒ 相=220V,30° 移相)可经 Lbal​=0.5mH(平衡电抗)或直接短(大 L_dc 下均流尚可)✅ 直流输出纹波频率 = 12·f_line(vs 6·f_line)直流输出 → Ldc​=50mH→Cdc​=2200µF→R=30Ω。Line‑Line RMS = 380 V(⇒ 相=220V)Vdc​≈1.35⋅380≈513V(同 6‑脉波)

xiaoheshang_123的博客 59

Allegro如何进行四层板板层设计

板层的设计

weixin_42499230的博客 3190

Javascript元编程

元编程中的生成代码是一种动态扩展程序能力的核心技术,通过字符串拼接、模板化代码生成或 AST 操作等方式,可以实现动态函数构造、逻辑优化、框架自动化等功能。尽管生成代码提高了开发效率和代码灵活性,但需要在性能、安全性和复杂性之间取得平衡。

你好呀 857

Raspberry Pi Pico + Inmp441麦克风(Pio模拟I2s)<2>

摘要:本文介绍了在Raspberry Pi Pico上使用PIO(Programmable I/O)接收I2S数字麦克风音频数据并保存为WAV文件的方法。项目采用双PIO状态机设计,一个生成I2S时钟信号(WS+SCK),另一个接收24位左声道数据并转换为16位格式。文章详细说明了接线方式、参数设置、WAV文件头构造、PIO汇编程序实现以及数据转换处理流程。项目在MicroPython环境下实现16kHz采样率、6秒时长录音,具有时序精确、稳定可靠的特性,并提供了进一步拓展的可能性,如双声道支持、实时频谱分

技术需要沉淀,需要碰撞。 660

C++基础之元编程与constexpr

元编程(metaprogramming)是一个典型的复合词,他由前缀 meta- 和词根 programming 复合而成,有“对一个程序进行编程”的意思。换句话说,编译器先编译你的代码,得到一份新的代码,然后再编译新的代码来解决问题。 模板元编程技术,即把一些可以在编译时完成的求值计算,通过模板特化的技术绑定到具体的实例化代码上,从而减少不必要的代码量,提升代码的运行效率。 一、C++的元编程 1.1 为什么要元编程呢? 前面我们知道了什么是元编程,那么为什么要有这种编写技巧呢? 无外乎两点:减少重复的代

weixin_42244181的博客 2872

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【元编程】混合元编程

元编程还有一种功能,成为混合元编程。1程序员写出一段元编程代码2编译器根据这段代码编译出一段新代码,实现程序真正功能的是这段生成的新代码3编译器会对这段新代码进行编译,产生最终的可执行程序。也就是说,混合元编程可以看作是运行期间的C代码生成器。

Antonio915的博客 1038

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: Elastic 的成功上市:偶然和必然
下一篇: 学习还是得死磕啊
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值