必威体育Betway必威体育官网
当前位置:首页 > IT技术

Ant入门

时间:2019-06-25 06:43:12来源:IT技术作者:seo实验室小编阅读:56次「手机版」
 

ant

前言

Ant是较早期的一种项目构建工具,在2000年就已出现,是当时比较流行的Java构建工具,它采用XML作为配置文件,有自己的一套构建过程控制标签,它的优点是对工程构建的过程控制比较好,它的缺点是build.xml文件比较大,开发人员需要编写繁杂的标签,属性等。当然项目构建工具还有现在比较常用的 Maven 和 Gradle。

Maven也是采用 XML作为配置文件,支持网络下载的功能,他的优点的要优点是生命周期,缺点是依赖管理不能很好地处理相同库文件不同版本之间的冲突。

Gradle 是个自动话的构建工具,兼具Ant和Maven的优点,即既有灵活性,又有声明周期管理,了解Android开发的人员都知道Gradle作为了Android的御用管理工具,它不再采用 XML作为配置文件,二是采用DSL格式,使得脚本更加清晰简洁,它的配置文件是一个Groovy文件。

下载安装

从官网下载Ant包,我下载的是Windows版

在这里插入图片描述

解压到任意一个目录 ,并添加到系统环境变量。

验证是否安装成功,如下图:

在这里插入图片描述

Ant使用说明

Ant构建文件build.xml

Ant 的构建文件默认为 build.xml,默认放在项目顶层目录中。看如下一个例子,创建一个文件命名为 build.xml 的文件,存储在你电脑的任意地方,输入内容:

<?xml version="1.0"?>
   <project name="FirstProject" default="info">
   <target name="info">
      <echo>Hello Worldt!</echo>
   </target>
</project>

构建文件的项目元素 有 3 个属性:

属性 描述
name 项目的名称 (可选)
default 构建脚本默认运行的目标,即指定默认的 target。一个项目 (project) 可以包含多个目标 (target)。(必须)
basedir 表示当该属性没有指定时,使用 Ant 的构件文件的附目录作为基准目录。(可选)

一个目标 (target) 包含一系列你想运行的任务 (tasks),运行时看成一个单元。目标和目标之间可以有依赖关系。一个部署 (deploy) 目标可能依赖于封装 (package) 目标,而这个封装目标可能又依赖于编译 (compile) 目标等。依赖关系被表示成依赖属性 (depends)。

<target name="deploy" depends="package">
</target>

<target name="package" depends="clean,compile">
</target>

<target name="clean" >
</target>

<target name="compile" >
</target>

构建文件的目标元素有以下属性:

属性 描述
name 目标的名称 (必须)
depends 描述 target 之间的依赖关系,与多个 target 存在依赖关系时,需以“,”隔开 (可选)
description 关于target功能的简单描述(可选)
if 验证指定的属性是否存在,若不存在,所在target 不会被执行 (可选)
unless 与 if 属性功能相反,指定属性不存在,所在 target 将会被执行

上面的例子中 echo 是指打印消息,在build.xml 文件所在目录执行 ant 命令

在这里插入图片描述

Ant属性

Ant 使用属性 (property) 元素来让你能够具体说明属性。这就允许这些属性能够在不同的构建和不同的环境下发生改变。

默认情况下,Ant 提供以下预定义的属性,这些属性都是可以在构建文件中使用的:

属性 描述
ant.file 构建文件的完整地址
ant.version 安装的Apache Ant 的版本
basedir 构建文件的基目录的绝对路径
ant.java.verison Ant 使用的 JAVA 语言的软件开发工具包的版本
ant.project.name 项目的名字
ant.project.default-target 当前项目的默认目标
ant.project.invoked-targets 在当前项目中被调用的目标的逗号分隔列表
ant.core.lib Ant 的 jar 文件的完整的地址
ant.home Ant 安装的主目录
ant.library.dir Ant 库文件的主目录

Ant 也确保系统属性在构建文件中可用,如 file.separator。

除了上述内容以外,用户也可以使用 property 元素定义一些额外的属性,smaple:

<?xml version="1.0"?>
<project name="HelloProject" default="info">
   <property name="sitename" value="www.baidu.com"/>
   <target name="info">
      <echo>Apache Ant version is ${ant.version} - You are at ${sitename} </echo>
   </target>
</project>

在这里插入图片描述

Ant属性文件

当项目只需对小部分属性进行设置时,可以选择直接在构建文件中设置。然而,对于大项目,最好将设置属性的信息存储在一个独立的文件中。

一般情况下,属性文件都被命名为 build.properties, 并且与 build.xml 存放在同一目录层。 可以基于部署环境 ——比如: build.properties.dev 和 build.properties.test 创建多个 build.properties 文件。sample:

build.xml

<?xml version="1.0"?>
<project name="HelloProject" default="info">

   <property file="build.properties"/>

   <target name="info">
      <echo>Apache Ant version is ${ant.version} - You are at ${sitename} </echo>
   </target>

</project>

build.properties

sitename=www.powerkong.com
buildversion=3.3.1

Ant数据类型

文件集

文件集的数据类型代表了一个文件集合。它被当作一个过滤器,用来包括或移除匹配某种模式的文件。

观察如下一个 sample,文件集选择源文件夹中所有的 .java 文件,除了那些包含有 ‘Stub’ 单词的文件。能区分大小写的过滤器被应用到文件集上,这意味着名为 Samplestub.java 的文件将不会被排除在文件集之外。

<fileset dir="${src}" casesensitive="yes">
   <include name="**/*.java"/>
   <exclude name="**/*Stub*"/>
</fileset>
模式集合

一个模式集合指的是一种模式,基于这种模式,能够很容易地过滤文件或者文件夹。模式可以使用下述的元字符进行创建。

  • ?-仅匹配一个字符
  • * -匹配零个或者多个字符
  • ** -递归地匹配零个或者多个目录

A sample:

<patternset id="java.files.without.stubs">
   <include name="src/**/*.java"/>
   <exclude name="src/**/*Stub*"/>
</patternset>

该模式集合能够通过一个类似于下述的文件集进行重用:

<fileset dir="${src}" casesensitive="yes">
   <patternset refid="java.files.without.stubs"/>
</fileset>
文件列表

文件列表数据类型与文件集类似,区别在于:

  • 文件列表包含明确命名的文件的列表,同时其不支持通配符。
  • 文件列表数据类型能够被应用于现有的或者还不存在的文件中。

    A sample:

<filelist id="config.files" dir="${webapp.src.folder}">
   <file name="applicationConfig.xml"/>
   <file name="faces-config.xml"/>
   <file name="web.xml"/>
   <file name="portlet.xml"/>
</filelist>
过滤器集合

使用一个过滤器集合数据类型与拷贝任务,可以在所有文件中使用一个替换值来替换掉一些与模式相匹配的文本。

一个常见的例子就是对一个已经发行的说明文件追加版本号,如下:

<copy todir="${output.dir}">
   <fileset dir="${releasenotes.dir}" includes="**/*.txt"/>
   <filterset>
      <filter token="VERSION" value="${current.version}"/>
   </filterset>
</copy>
  • 属性 output.dir 指向项目的输出文件夹。
  • 属性 releasenotes.dir 指向项目的发行说明文件夹。
  • 属性current.version 指向项目的当前版本文件夹。
  • 拷贝任务,顾名思义,是用来将文件从一个地址拷贝到另一个地址。
路径

path 数据类型通常被用来表示一个类路径。各个路径之间用分号或者冒号隔开。然而,这些字符在运行时被替代为执行系统的路径分隔符。

类路径被设置为项目中 jar 文件和类文件的列表,如下面例子所示:

<path id="build.classpath.jar">
   <pathelement path="${env.J2EE_HOME}/${j2ee.jar}"/>
   <fileset dir="lib">
      <include name="**/*.jar"/>
   </fileset>
</path>
  • 属性env.J2EE_HOME指向环境变量 J2EE_HOME
  • 属性j2ee.jar 指向 J2EE 基础文件夹下面的名为 J2EE jar的文件。

Ant 编译项目

A sample:

<?xml version="1.0"?>
<project name="fax" basedir="." default="build">
   <property name="src.dir" value="src"/>
   <property name="web.dir" value="war"/>
   <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
   <property name="name" value="fax"/>

   <path id="master-classpath">
      <fileset dir="${web.dir}/WEB-INF/lib">
         <include name="*.jar"/>
      </fileset>
      <pathelement path="${build.dir}"/>
   </path>

   <target name="build" description="Compile source tree java files">
      <mkdir dir="${build.dir}"/>
      <javac destdir="${build.dir}" source="1.5" target="1.5">
         <src path="${src.dir}"/>
         <classpath refid="master-classpath"/>
      </javac>
   </target>

   <target name="clean" description="Clean output directories">
      <delete>
         <fileset dir="${build.dir}">
            <include name="**/*.class"/>
         </fileset>
      </delete>
   </target>
</project>

首先,声明源文件 src, web 文件 和构建文件的一些属性信息

<property name="src.dir" value="src"/>
<property name="web.dir" value="war"/>
<property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
  • src.dir 表示这个项目的源文件目录,即是存储 java 文件的地方。
  • web.dir 表示这个项目的 web 文件目录,也就是存储 JSP文件, web.xml,CSS,JavaScript 以及其他 Web 相关文件的地方
  • build.dir 表示该项目的输出文件

属性也可以引用其它属性。在上面的例子中,build.dir 属性引用了 web.dir 属性。

我们项目的默认目标是编译目标。但是首先让我们来看一下 clean 目标。clean 目标用于删除构建文件夹中的所有文件。

<target name="clean" description="Clean output directories">
   <delete>
      <fileset dir="${build.dir}">
         <include name="**/*.class"/>
      </fileset>
   </delete>
</target>

控制类路径 (master-classpath) 保存类路径的相关信息。在这种情况下,它包含了构建文件夹和 jar 文件夹中的所有的类文件。

<path id="master-classpath">
   <fileset dir="${web.dir}/WEB-INF/lib">
      <include name="*.jar"/>
   </fileset>
   <pathelement path="${build.dir}"/>
</path>

Ant生成文档

JDK 中内置Javadoc工具,使得Java生成文档十分方便,而Ant可以按需生成文档,使得这个步骤更加简单。##### 属性

javadoc 任务属性:

  • 源路径(sourcepath),指向源文件所在的文件夹,如 src 文件夹
  • 源路径引用(sourcepathref),指向由该路径属性引用的路径,例如:delegates.src.dir 。
  • 源文件 (sourcefiles), 在你想指定单独的文件时使用,比如指定一个逗号分隔列表。
  • 目标路径(destdir),目标路径是通过使用 destdir 文件夹来指定的,例如 build.dir 。
  • packagenames,通过指定应被包括的包的名字来过滤 javadoc 任务,一个以逗号分隔的包文件列表。
  • group,将所有的包组织在一起,以使得他们更易被操作。

A sample:

<target name = "generate-javadoc">
   <javadoc packagenames="faxapp.*" sourcepath="${src.dir}" 
      destdir = "doc" version = "true" windowtitle = "Fax Application">

      <doctitle><![CDATA[= Fax Application =]]></doctitle>

      <bottom>
         <![CDATA[Copyright © 2011. All Rights Reserved.]]>
      </bottom>

      <group title = "util packages" packages = "faxapp.util.*"/>
      <group title = "web packages" packages = "faxapp.web.*"/>
      <group title = "data packages" packages = "faxapp.entity.*:faxapp.dao.*"/>
   </javadoc>
   <echo message = "java doc has been generated!" />
</target>

在这个例子中,我们指定 javadoc 去使用 src.dir 作为源目录,doc 作为目标,定制窗口标题,标题,以及显示在 java 文档页上的页脚信息。

还创建了三个组:

  • 为源文件夹中的实用工具类创建了一个组。
  • 为用户接口的类创建了一个组。
  • 为数据库相关的类创建了一个组。 您可能会注意到,数据包组含有两个包:faxapp.entity 和 faxapp.dao 。

运行该target:

>C:\>ant generate-javadoc
>Buildfile: C:\build.xml

>java doc has been generated!

>BUILD SUCCESSFUL
>Total time: 10.63 second

Ant 生成 jar文件

编译完 Java 源文件后,可以使用 ant 的 jar 任务来将编译后的类打包。

jar任务属性:

属性 描述
basedir 表示输出 JAR 文件的基目录。默认情况下,为项目的基目录
compress 表示告知 Ant 对于创建的 JAR 文件进行压缩。
keepcompression 表示 project 基目录的绝对路径。
destfile 表示输出 JAR 文件的名字
duplicate 表示发现重复文件时 Ant 执行的操作。可以是添加、保存、或者是使该重复文件失效。
excludes 表示移除的文件列表,列表中使用逗号分隔多个文件。
excludesfile 与上同,但是使用模式匹配的方式排除文件。
include 表示包含的文件列表,列表中使用都好分隔多个文件
includesfile 与上同,但是使用模式匹配的方式排除文件
update 表示告知 Ant 重写已经建立的 JAR 文件。

A sample:

<jar destfile = "${web.dir}/lib/util.jar"
   basedir = "${build.dir}/classes"
   includes = "faxapp/util/**"
   excludes = "**/Test.class" />

web.dir 属性表示 web 源文件的路径,build.dir 属性表示配置文件夹的存储路径。

在上面的代码中,利用来自 faxapp.util 包中的类文件创建了一个名为 util.jar 的 jar 包,并排除名字为 Test 的类文件。输出的 jar 文件将会存放在 web 应用的配置文件 lib 中。

如果想 util.jar 成为可执行文件,只需在 Main-Class 元属性中加入manifest. 这样,上面给出的代码,在加入 Main-Class 元属性后,可以更新为如下形式:

<jar destfile = "${web.dir}/lib/util.jar"
   basedir = "${build.dir}/classes"
   includes = "faxapp/util/**"
   excludes = "**/Test.class">
   <manifest>
      <attribute name = "Main-Class" value = "com.tutorialspoint.util.FaxUtil"/>
   </manifest>
</jar>

为了执行 jar 任务,将它包装在目标 target 中,最常见的情况是,将 jar 任务包装在配置目标或者打包目标中(build 目标或 package 目标),并执行包装后的目标。

<target name="build-jar">
   <jar destfile="${web.dir}/lib/util.jar"
      basedir="${build.dir}/classes"
      includes="faxapp/util/**"
      excludes="**/Test.class">
      <manifest>
         <attribute name="Main-Class" value="com.tutorialspoint.util.FaxUtil"/>
      </manifest>
   </jar>
</target>

Ant 生成 war 文件

WAR 任务是 JAR 任务的一个扩展,但是其对控制哪些文件进入 WEB-INF/classes 文件夹和生成 web.xml 文件进行了一些很好的补充。WAR 任务对指定 WAR 文件布局是非常有用的,相关属性:

属性 描述
webxml web.xml 文件的路径
lib 指定哪些文件可以进入 WEB-INF\lib 文件夹的一个组
classes 指定哪些文件可以进入 WEB-INF\classes 文件夹的一个组
metainf 指定生成 MANIFEST.MF 文件的指令

A sample:

<war destfile = "fax.war" webxml = "${web.dir}/web.xml">

   <fileset dir = "${web.dir}/WebContent">
      <include name = "**/*.*"/>
   </fileset>
   
   <lib dir = "thirdpartyjars">
      <exclude name = "portlet.jar"/>
   </lib>
   <classes dir = "${build.dir}/web"/>
</war>

web.dir 变量指向源 web 文件夹,即该文件包含 JSP,css 和 javascript 文件等等。

该 build.dir 变量指向输出文件夹,WAR 的包能在该文件夹下找到。 通常情况下, 类将被绑定到 WAR 文件下的 WEB-INF/classes 文件夹下。

在这个例子中,我们创建了一个名为 fax.war 的 war 文件。WEB.XML 文件可以从 web 源文件中获取。 所有 web 下来自 “WebContent” 的文件都被复制到 WAR 文件中。

WEB-INF/lib 文件夹中存储了来自于第三方 jar 文件夹中的 jar 文件。但是,我们排除了 portlet.jar,因为该 jar 文件已经存在于应用服务器的 lib 文件夹中了。最后,我们从一个构建目录下的 web 文件夹中复制所有的类,并将复制的类全部放入 WEB-INF/classes 文件夹下。

要执行 war 任务,将其封装在一个目标里面,最常见的是,构建目标或者是包目标,然后运行它们。

A sample:

<target name="build-war">

   <war destfile="fax.war" webxml="${web.dir}/web.xml">
      <fileset dir="${web.dir}/WebContent">
         <include name="**/*.*"/>
      </fileset>

      <lib dir="thirdpartyjars">
         <exclude name="portlet.jar"/>
      </lib>

      <classes dir="${build.dir}/web"/>
   </war>

</target>

执行 target: ant build-war

该 fax.war 文件当前被放置在输出文件夹中。war 文件的内容结构:

fax.war:

  • jsp :这个文件夹包含了 jsp 文件

  • css :这个文件夹包含了 stylesheet 文件

  • js :这个文件夹包含了 javascript 文件

  • images:这个文件夹包含了 image 文件

  • META-INF:这个文件夹包含了 Manifest.Mf

  • WEB-INF

        classes :这个文件夹包含了编译好的类
        lib :第三方库和使用程序 jar 文件
        WEB.xml :定义 WAR 包的配置文件 
    

Ant 部署应用

直接将 web 应用程序部署到一个应用服务器的部署文件夹中,并添加一些 Ant 目标来启动和停止服务。

创建一个资源引用文件

build.properties
# Ant properties for building the springapp

appserver.home=c:\\install\\apache-tomcat-7.0.19
# for Tomcat 5 use $appserver.home}/server/lib
# for Tomcat 6 use $appserver.home}/lib
appserver.lib=${appserver.home}/lib

deploy.path=${appserver.home}/webapps

tomcat.manager.url=http://www.tutorialspoint.com:8080/manager
tomcat.manager.username=tutorialspoint
tomcat.manager.password=secret

创建 ant build 文件

build.xml
<?xml version="1.0"?>

<project name="fax" basedir="." default="usage">
   <property file="build.properties"/>
   <property name="src.dir" value="src"/>
   <property name="web.dir" value="war"/>
   <property name="javadoc.dir" value="doc"/>
   <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
   <property name="name" value="fax"/>

   <path id="master-classpath">
      <fileset dir="${web.dir}/WEB-INF/lib">
         <include name="*.jar"/>
      </fileset>
   <pathelement path="${build.dir}"/>
   </path>

   <target name="javadoc">
      <javadoc packagenames="faxapp.*" sourcepath="${src.dir}" 
         destdir="doc" version="true" windowtitle="Fax Application">

         <doctitle><![CDATA[<h1>= Fax Application = </h1>]]></doctitle>
         <bottom><![CDATA[Copyright © 2011. All Rights Reserved.]]></bottom>
         <group title="util packages" packages="faxapp.util.*"/>
         <group title="web packages" packages="faxapp.web.*"/>
         <group title="data packages" packages="faxapp.entity.*:faxapp.dao.*"/>

      </javadoc>
   </target>

   <target name="usage">
   <echo message=""/>
   <echo message="${name} build file"/>
   <echo message="-----------------------------------"/>
   <echo message=""/>
   <echo message="Available targets are:"/>
   <echo message=""/>
   <echo message="deploy    --> Deploy application as directory"/>
   <echo message="deploywar --> Deploy application as a WAR file"/>
   <echo message=""/>
   </target>

   <target name="build" description="Compile main source tree java files">
   <mkdir dir="${build.dir}"/>
      <javac destdir="${build.dir}" source="1.5" target="1.5" debug="true"
         deprecation="false" optimize="false" failonerror="true">
         <src path="${src.dir}"/>
         <classpath refid="master-classpath"/>
      </javac>
   </target>

   <target name="deploy" depends="build" description="Deploy application">
      <copy todir="${deploy.path}/${name}" 
         preservelastmodified="true">
         <fileset dir="${web.dir}">
            <include name="**/*.*"/>
         </fileset>
      </copy>
   </target>

   <target name="deploywar" depends="build" description="Deploy application as a WAR file">
      <war destfile="${name}.war" webxml="${web.dir}/WEB-INF/web.xml">
         <fileset dir="${web.dir}">
            <include name="**/*.*"/>
         </fileset>
      </war>

      <copy todir="${deploy.path}" preservelastmodified="true">
         <fileset dir=".">
            <include name="*.war"/>
         </fileset>
      </copy>
   </target>

   <target name="clean" description="Clean output directories">
      <delete>
         <fileset dir="${build.dir}">
            <include name="**/*.class"/>
         </fileset>
      </delete>
   </target>

<!-- ============================================================ -->
<!-- Tomcat tasks -->
<!-- ============================================================ -->

<path id="catalina-ant-classpath">
<!-- We need the Catalina jars for Tomcat -->
<!--  * for other app servers - check the docs -->
   <fileset dir="${appserver.lib}">
      <include name="catalina-ant.jar"/>
   </fileset>
</path>

<taskdef name="install" classname="org.apache.catalina.ant.InstallTask">
   <classpath refid="catalina-ant-classpath"/>
</taskdef>
<taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask">
   <classpath refid="catalina-ant-classpath"/>
</taskdef>
<taskdef name="list" classname="org.apache.catalina.ant.ListTask">
   <classpath refid="catalina-ant-classpath"/>
</taskdef>
<taskdef name="start" classname="org.apache.catalina.ant.StartTask">
   <classpath refid="catalina-ant-classpath"/>
</taskdef>
<taskdef name="stop" classname="org.apache.catalina.ant.StopTask">
   <classpath refid="catalina-ant-classpath"/>
</taskdef>

<target name="reload" description="Reload application in Tomcat">
   <reload url="${tomcat.manager.url}"username="${tomcat.manager.username}"
      password="${tomcat.manager.password}" path="/${name}"/>
</target>
</project>

在这个例子中,我们已经使用 Tomcat 作为我们应用的服务器。 首先,在构建属性文件中,定义了一些附加属性。

  • appserver.home 指向 Tomcat 服务器的安装路径。
  • appserver.lib 指向 Tomcat服务器的安装文件下的库文件。
  • deploy.path 变量当前指向 Tomcat 的 web 应用程序文件夹。

在 Tomcat 中的应用程序能通过使用 Tomcat 管理应用程序进行启动和停止。管理应用程序的统一资源定位器(URL),用户名和密码也在 build.properties 文件夹中进行指定。 接下来,我们声明一个新的 CLASSPATH 来包含 catalina-ant.jar。 若要通过 Apache Ant 来运行 Tomcat, 这个 jar 文件是必须的。

catalina-ant.jar 提供了下述的任务:

属性 描述
InstallTask 安装一个 web 应用程序。 类名字为: org.apache.catalina.ant.InstallTask
ReloadTask 重新安装一个 web 应用程序。类名字为: org.apache.catalina.ant.ReloadTask
ListTask 列出所有的 web 应用程序。类名字为: Class Name: org.apache.catalina.ant.ListTask
StartTask 启动一个 web 应用程序。类名字为: org.apache.catalina.ant.StartTask
StopTask 停止一个 web 应用程序。类名字为: org.apache.catalina.ant.StopTask

reload (重载任务) 需要下列附加参数:

  • 管理应用程序的 URL
  • 重启 web 应用程序的用户名
  • 重启 web 应用程序的密码
  • 重启的 web 应用程序的名字

执行 war (deploy-war)的命令来复制 web 应用程序到 Tomcat 的 webapps 文件夹中。同时重新加载 web 应用程序。

>C:\>ant deploy-war
>Buildfile: C:\build.xml

>BUILD SUCCESSFUL
>Total time: 6.3 seconds

>C:\>ant reload
>Buildfile: C:\build.xml

>BUILD SUCCESSFUL
>Total time: 3.1 seconds

注:本文参考 w3cschool教程进行学习整理。

相关阅读

Ricequant米矿【MACD策略代码解释】量化交易

解释: 下面定义了四个函数。但是,其实只用了第一个函数,跟最后一个函数。这两个函数是必有的。 多定义的这几个函数 getPrice,跟get

build Variants创建不同配置的app(图文详解)

现象描述 开发一个app避免不了在多种环境下运行,比如开发环境、测试环境、正式环境,而根据不同环境要配置不同的变量,在以前,我都是通

MFC之COleVariant

COleVariant 本质上是一个枚举,用同一种类型来表达不同的子类型。如同boost中的variant。例子COleVariant var(3.6f); float v =

圣魔大战3(Castle Fantisia)艾伦希亚战记修改器/秘籍—

艾伦西亚战记== 艾伦希亚战记,是一个游戏武器:UltraEdit(金山游侠自带的文件修改器也可以,只是这个专业)目标: 存档文件(建议先备份) 

量子隐形传送(Quantum Teleportation)初学

                     量子隐形传送(Quantum Teleportation)初学 本文参考自http://blog.sciencenet.cn/blog-871282-9

分享到:

栏目导航

推荐阅读

热门阅读