精华内容
下载资源
问答
  • Perl中的符号表 概念 通常来说,我们写一段代码需要为它提供一个命名空间,这样变量和函数才不会其他人的变量或者函数产生冲突,反之亦然。 包是独立文件的。一个文件通常可以包含多个包,或者一个包可以跨多个...

    Perl中的符号表

    概念

    通常来说,我们写一段代码需要为它提供一个命名空间,这样变量和函数才不会与其他人的变量或者函数产生冲突,反之亦然。
    包是独立于文件的。一个文件通常可以包含多个包,或者一个包可以跨多个文件。通俗来讲包就是perl的模块,通常以.pm结尾,并且在定义一个包时,文件名与包名相同。
    也有极个别情况,文件名与包名不相同,通常发生在一个文件中定义了多个包,所以它有好几个包名,因此文件名与包名不相同。典型的例子就是VMware官方的Perl
    SDK开发模块。
    通常在使用模块化编程时,我们需要学习如何保护不同的代码块,让它们不会意外地破坏其他代码块的变量。每个代码块都属于一个特定的包,包确定了这个代码块中可用的变量和子例程。
    初始的包名为main,在其他编程语言中例如ruby,称为顶层堆栈。我们可以通过package关键字来从当前包切换到另外一个包。当前包确定了要使用哪个符号表来查找变量,子例程,I/O句柄和格式。

    符号表

    包的内容称为符号表。它存储在一个哈希中,这个散列与包同名,不过需要带上两个冒号、因此main包的符号表就为%main::,
    由于main是默认包,Perl提供了%::作为%main::的简写形式。
    类似地,Red::Blue包的符号表名为%Red::Blue::,
    由于main符号表包含所有其他顶层符号表,
    包括它本身,所以%Red::Blue::也就是%main::Red::Blue.
    通常一个符号表包含另一个符号表时,是指它包含另一个符号表的引用。由于main是顶层包,所以它包含它自己的一个引用,所以%main::就等同于%main::main::,以此类推,无穷无尽。。

    say map { "$_ => $main::{$_}\n" } keys %main::;
    
    # ARNING_BITS => *main::ARNING_BITS
    # . => *main::.
    # STDERR => *main::STDERR
    # ENV => *main::ENV
    #  => *main::
    # UNIVERSAL:: => *main::UNIVERSAL::
    # E_COMPILE_RECURSION_LIMIT => *main::E_COMPILE_RECURSION_LIMIT                                                                                                      => *main::
    # feature:: => *main::feature::
    # version:: => *main::version::
    # INC => *main::INC
    # stdin => *main::stdin
    # _ => *main::_
    # " => *main::"
    # ARGV => *main::ARGV
    # warnings:: => *main::warnings::
    #  => *main::
    # STDIN => *main::STDIN
    #  => *main::
    # Regexp:: => *main::Regexp::
    # constant:: => *main::constant::
    # stderr => *main::stderr
    # Carp:: => *main::Carp::
    # , => *main::,
    # 1 => *main::1
    # PerlIO:: => *main::PerlIO::
    # mro:: => *main::mro::
    # DynaLoader:: => *main::DynaLoader::
    # Exporter:: => *main::Exporter::
    #  => *main::
    # / => *main::/
    # IO:: => *main::IO::
    # strict:: => *main::strict::
    # utf8:: => *main::utf8::
    # Internals:: => *main::Internals::
    # stdout => *main::stdout
    # BEGIN => *main::BEGIN
    # STDOUT => *main::STDOUT
    # main:: => *main::main::
    # @ => *main::@
    # 0 => *main::0
    # DB:: => *main::DB::
    # 
    # AST_FH => *main::
    #                  AST_FH
    # 2 => *main::2
    # re:: => *main::re::
    # CORE:: => *main::CORE::
    

    在一个符号表中,每个键值对将一个变量名映射到这个变量的值。键是符号标识符,值是相应的类型团。所以使用*NAME型团记法时,实际上就是在访问散列的值。

    *sym = *main::variable
    *sym = $main::{'variable'};
    

    第一种更加高效一些,因为这会在编译时访问main符号表。如果之前不存在这样的类型团,它还会创建一个新的类型团,第二种则不会。
    实际上,我们可以使用想要的任何字符串作为符号表散列中的键。不过如果使用一个非标识符,则是不合法的。
    对类型团的赋值是一个别名操作,也就是说:

    *dick = *richard;
    

    那么可以通过标识符richard访问的变量,子例程,格式,文件和目录句柄也可以通过dick来访问。如果只是想对某个特定的变量或子例程指定别名,那么可以对一个引用赋值;

    our $ricard = 10;
    *dick = \$ricard;
    print $dick; # 10
    

    这会使ricard和dick变成同一个变量。
    Exporter模块从一个包向另一个包导入符号表时就是这样做的。例如:

    *SomePack::dick = &otherPack::ricard;
    

    如果在赋值前面加上local,这个别名操作只会持续到当前动态作用域结束。
    可以利用这个机制从子例程获取引用,使指示对象可以作为一个适当的数据类型;

    
    sub populate {
        my %newhash = (
            km => 20,
            kg => 70,
        );
        return \%newhash;
    }
    
    {
        no strict;  # 由于没有my声明变量,在stric模式下会产生错误,因此在局部作用域中执行,并且关闭stric模式
        *unit = populate();
        say $unit{km}; # 无需解引用,像正常哈希取值一样
    }
    
    {
        no strict;
        %units = (miles => 6, stones => 11);
        filerup(\%units);
    
    
        sub filerup {
            local *units = shift;
            say $units{miles};
        }
    }
    

    如果不想显示解引用,可以取巧用这种办法,但是my声明的变量由于不在符号表中,因此无法使用这种形式。
    符号表的另外一个用法是建立常量:

    *PI = \3.1415926;
    

    这种形式与常量子例程不同,常量子例程在编译时优化。可以用另外两种形式来建立常量:

    use constant PI => 3.1415926;
    
    *PI = sub () { 3.1415926 };
    

    将sub {}赋至一个类型团是在运行时为匿名子例程指定名字的一种方法。
    将类型团引用赋至另一个类型团(*sym =
    *oldvar)等同于赋值整个类型团,因为perl会自动对这个类型团解引用。将类型团设置为一个简单的字符串时,会得到用这个字符串命名的整个类型团,因为perl会在当前符号表中查找这个字符串。下面的代码是等价的,只不过前面两个会在编译时计算符号表记录,而后面两个会在运行时计算;

    {
        no strict;
        *sym = *oldvar;
        *sym = \*oldvar;
        *sym = *{'oldvar'}; #显示符号表查找
        *sym = "oldvar"; # 隐示符号表查找
    }
    

    完成以下赋值时,只是替换了类型团中的一个引用

    {
        no strict;
        *sym = \$oldvar;
        *sym = \@oldvar;
        *sym = \%oldvar;
        *sym = \&pippin;
    }
    

    类型团本身可以看做是一种散列,其中包含了对应不同变量类型的记录。在这里,键是固定的,因为类型团只可能包含一个标量,一个数组,一个散列等。不过可以取出单个引用,如下所示:

    *pkg::sym{SCALAR} # 等同于\$pkg::sym
    *pkg::sym{ARRAY}  # 等同于\@pkg::sym
    *pkg::sym{HASH}   # 等同于\%pkg::sym
    *pkg::sym{CODE}   # 等同于\&pkg::sym
    *pkg::sym{GLOB}   # 等同于\*pkg::sym
    *pkg::sym{IO}     # 内部文件/目录句柄
    *pkg::sym{NAME}    # "sym" 不是一个引用
    *pkg::sym{PACKAGE} # "pkg" 不是一个引用
    
    

    可以用*foo{PACKAGE}和*foo{NAME}查找*foo符号表记录来自哪个包和名字。对于传入类型团作为参数的子例程来说,这可能很有用:

    {
        sub identify_typeglob {
            my $glob = shift;
            say "You gave me " . *{$glob}{PACKAGE} . "::" . *{glob}{NAME};
        }
    
        identify_typeglob(*glob); # You gave me main::glob
    }
    

    符号表引用

    写程序时,我们可能不知道需要什么类型的引用。引用可以使用一些特殊的方式创建,这称为*foo{THING},
    它会返回*foo中THING槽的引用,这是一个符号表记录,其中包含$foo, %foo,
    @foo等的值。

    
    $scalar_ref = *foo{SCALAR}; # 等同于\$foo
    $array_ref = *foo{ARRAY}; # 等同于\@foo
    $hash_ref = *foo{HASH};   # 等同于\%foo
    $code_ref = *foo{CODE};   # 等同于\&foo
    $glob_ref = *foo{GLOB};   # 等同于\*foo
    $io_ref = *STDIN{IO};     # ...
    $format = *foo{FORMAT};   # ...
    

    *foo{FORMAT}可以得到使用format语句声明的对象,利用它们做不了太多有趣的事情。
    另一方面*STDIN{IO}会得到类型团包含的具体的内部IO::Handle对象,也就是说,类型团中各个I/O函数真正感兴趣的部分。
    理论上讲只要是\*HANDLE或*HADNLE的地方都可以使用*HANDLE{IO}, 如向子例程传入或从子例程传出句柄,或者将它们存储在更大的数据结构中。它们的好处是只访问你想要的实际I/O对象,而不是整个类型团,所以不用担心类型团赋值会遇到太大的风险。

    slutter(*STDIN); slutter(*STDIN{IO});
    sub slutter {
        my $fh = shift; print $fh "her um well a hmmm\n";
    }
    

    以上两种调用形式结果完全相同
    如果编译器还没有看到特定的THING,*foo{THING}会返回undef,除非THING是SCALAR。*foo{SCALAR}会返回一个匿名变量引用,即使编译器没有看到$foo。perl总是为类型团增加一个标量,把这作为一个优化措施,以减少别处代码。

    简单的方法

    利用Package::Stash在包中创建类型团或者获取符号表

    {
        # 以下代码是利用Package::Stash模块来在main包中创建了*camel类型团
        no strict;
        use Package::Stash;
        my $foo_stash = Package::Stash->new("main");
        $foo_stash->add_symbol('$camel', 'Amelia');
        say $main::camel; # Amelia
        say $camel; # Amelia
        say *camel{SCALAR}->$*; # Amelia
    }
    
    
    

    获取当前包的符号表

    {
        use Package::Stash;
        my $foo_stash = Package::Stash->new("main");
        my $main_stash = $foo_stash->get_all_symbols;
        for my $key (keys %$main_stash) {
            say "$key => " . $main_stash->{$key};
        }
    }
    

    Note: strict对*foo并不起作用,它只对$foo和@foo等管用,因此为了消除错误警报,需要提前声明变量或者局部关闭变量检查,no strict ‘vars’;

    展开全文
  • 您为其提供了一个模式,该模式包含定义要生成的输出的符号,它将创建随机数据以匹配该模式。 特征 易于使用的语法。 类似正则表达式的表达式,很多人都熟悉。 支持简单模式或高级多模式模板。 可以生成随机数...
  • 基于二分查找插入排序的符号表容器 符号表就是类似编程常用的map,这里简单实现了一下 Api public ST()//构造器 private void expansion()//扩容容器 public Value get(Key key)//根据key获取value public...

    基于二分查找与插入排序的符号表容器

    符号表就是类似于编程常用的map,这里简单实现了一下

    Api

       public ST()//构造器
       private void expansion()//扩容容器
       public Value get(Key key)//根据key获取value
       public boolean containKey(Key key)//二分查找符号表是否包含这个key
       public int keyIndex(Key key)//二分查找符号表里key的下标
       public void put(Key key,Value value)//向容器里添加一个key-value对
       private void insertSort(Key key,Value value)//添加key-value对并进行插入排序
       public void delete(Key key)//删除key-value对
       public int size()//返回符号表的真实大小
       private void swapKey(int i,int j)//交换俩个key的位置
       private void swapValue(int i,int j)//交换俩个value的位置
       private boolean less(Key a,Key b)//如果a<b,返回true
       private boolean isEquals(Key a,Key b)//如果a=b,返回true
    

    实现

    //基于二分查找与插入排序的符号表
    //Key继承Comparable接口来保证良好的有序性
    public class BinarySt<Key extends Comparable,Value> {
       private Key[] keys;      //键数组
       private Value[] values;  //值数组
       private int N = 0;       //键的数量
       private int realSize = 0;//符号表的真实大小
       //构造器,初始大小为2
       public BinarySt(){
           keys = (Key[]) new Comparable[2];
           values = (Value[]) new Object[2];
       }
       //扩容容器
       private void expansion(){
           Key[] newKeys = (Key[]) new Comparable[N*7/4];
           Value[] newValues = (Value[]) new Object[N*7/4];
           System.arraycopy(keys,0,newKeys,0,N);
           System.arraycopy(values,0,newValues,0,N);
           keys = newKeys;
           values = newValues;
       }
       //根据key获取value
       public Value get(Key key){
           int index;
           return -1==(index=keyIndex(key))?null:values[index];
       }
       //二分查找符号表是否包含这个key
       public boolean containKey(Key key){
           int begin = 0;
           int end = keys.length - 1;
           int mid;
           while (begin<=end){
               mid = (begin+end)/2;
               if (isEquals(key,keys[mid])){
                   return null==values[mid]?false:true;
               }else if (less(key,keys[mid])){
                   end = mid-1;
               }else {
                   begin = mid+1;
               }
           }
           return false;
       }
       //二分查找符号表里key的下标
       public int keyIndex(Key key){
           int begin = 0;
           int end = N-1;
           int mid;
    
           while (begin<=end){
               mid = (begin+end)/2;
               if (isEquals(key,keys[mid])){
                   return mid;
               }else if (less(key,keys[mid])){
                   end = mid-1;
               }else {
                   begin = mid+1;
               }
           }
           return -1;
       }
       //向容器里添加一个key-value对
       public void put(Key key,Value value){
           if (N == keys.length){
               expansion();
           }
           int index;
           if (-1 == (index = keyIndex(key))){
               realSize++;
               insertSort(key,value);
           }else {
               values[index] = value;
           }
       }
       //添加key-value对并进行插入排序
       private void insertSort(Key key,Value value){
           keys[N++] = key;
           values[N-1] = value;
           for (int i = N-1; i > 0; i--) {
               if (less(keys[i],keys[i-1])){
                   swapKey(i,i-1);
                   swapValue(i,i-1);
               }
           }
       }
       //删除key-value对
       public void delete(Key key){
           put(key,null);
           realSize--;
       }
       //返回符号表的真实大小
       public int size(){
           return realSize;
       }
       //交换俩个key的位置
       private void swapKey(int i,int j){
           Key temp = keys[i];
           keys[i] = keys[j];
           keys[j] = temp;
       }
       //交换俩个value的位置
       private void swapValue(int i,int j){
           Value temp = values[i];
           values[i] = values[j];
           values[j] = temp;
       }
       //如果a<b,返回true
       private boolean less(Key a,Key b){
           return a.compareTo(b) < 0;
       }
       //如果a=b,返回true
       private boolean isEquals(Key a,Key b){
           return a.compareTo(b)==0;
       }
    }
    
    展开全文
  • 理论上完美可执行文件可以不包含任何符号; 之所以有可执行文件包含符号,是为了支持语言运行时特点;比如c++和oc; 更进一步,理论上只包含函数符号和地址对应关系即可,比如c++; 但是对于oc语言,变量...

    理论上完美的可执行文件可以不包含任何符号;

    之所以有的可执行文件包含符号,是为了支持语言的运行时特点;比如c++和oc;

    更进一步,理论上只包含函数符号和地址的对应关系即可,比如c++;

    但是对于oc语言,变量是作为运行时结构的一部分存在的,所以变量符号在可执行文件中也存在。

    转载于:https://www.cnblogs.com/feng9exe/p/7997945.html

    展开全文
  • C#中$符号的作用

    千次阅读 2019-04-25 00:21:54
    一:$符号的用法 $符号的作用相当对String....例如我们需要输出一段包含nameage字符串: using System; class Program { static void Main(string[] args) { string name = "liu"; int age = 10; ...

    一:$符号的用法

    $符号的作用相当于对String.format()的简化

    例如我们需要输出一段包含name与age的字符串:

    using System;
    
    class Program
    {
        static void Main(string[] args)
        {
            string name = "liu";
            int age = 10;
    
            //复杂麻烦的写法
            string str1 = "my name is " + name + ",my age is " + age + ".";
            //使用Format的写法
            string str2 = string.Format("my name is {0},my age is {1}.", name, age);
            //使用$语法糖的写法
            string str3 = $"my name is {name},my age is {age}.";
    
            //控制台的三个输出都相同
            Console.WriteLine(str1);
            Console.WriteLine(str2);
            Console.WriteLine(str3);
        }
    }

    ——由代码显然可见第一种写法复杂麻烦,使用起来是不方便的
    ——使用Format格式化这种写法,需要自己在字符串中写占位符(标记),在后面跟上参数。但是如果要格式化的参数比较多,写起来就比较麻烦
    ——使用$语法糖的写法可读性高,代码简洁。
    ——注意$与第一个"之前不能有空格

    因为C#是美国人发明的,所以用$符号,那么如果是中国人发明的C#或许这个语法糖就使用¥符号了吧.....


    二:Format格式化字符串

    DateTime dt = new DateTime(2017,4,1,13,16,32,108);
    string.Format("{0:y yy yyy yyyy}",dt); //17 17 2017 2017
    string.Format("{0:M MM MMM MMMM}", dt);//4  04 四月 四月
    string.Format("{0:d dd ddd dddd}", dt);//1  01 周六 星期六
    string.Format("{0:t tt}", dt);//下 下午
    string.Format("{0:H HH}", dt);//13 13
    string.Format("{0:h hh}", dt);//1  01
    string.Format("{0:m mm}", dt);//16 16
    string.Format("{0:s ss}", dt);//32 32
    string.Format("{0:F FF FFF FFFF FFFFF FFFFFF FFFFFFF}", dt);//1 1  108 108  108   108    108
    string.Format("{0:f ff fff ffff fffff ffffff fffffff}", dt);//1 10 108 1080 10800 108000 1080000
    string.Format("{0:z zz zzz}", dt);//+8 +08 +08:00
    
    string.Format("{0:yyyy/MM/dd HH:mm:ss.fff}",dt);  //2017/04/01 13:16:32.108
    string.Format("{0:yyyy/MM/dd dddd}", dt);      //2017/04/01 星期六
    string.Format("{0:yyyy/MM/dd dddd tt hh:mm}", dt); //2017/04/01 星期六 下午 01:16
    string.Format("{0:yyyyMMdd}", dt);         //20170401
    string.Format("{0:yyyy-MM-dd HH:mm:ss.fff}", dt); //2017-04-01 13:16:32.108

     

    展开全文
  • symbol池与符号

    2010-12-21 21:02:00
    通过Stringintern()函数,可以做到不同Symbol中包含的字符串一定是不同。再将Symbol应用Table中关键字,由此又可以做到对同样一个Symbol,可以再Hash表中同一格按先后顺序链上不同Binders。Binder内部...
  • 要启用这些调试消息,请在测试该项目或将make与包含该库任何其他项目一起使用时,将变量MK_ESCAPE_DEBUG设置为1 。 运行时依赖 在Makefile执行期间(解析阶段,而不是配方执行阶段),唯一需要程序是echo ,它...
  • 同时,融合特征有助网络结构获取更多全局信息,更好地表示公式符号的类别。利用在线手写数学表达式识别竞赛组织(CROHME)提供标准数学公式符号库来验证所提算法,结果表明,CROHME2014和CROHME2016识别率分别...
  • 符号执行简介

    2021-01-01 19:51:45
    符号执行起初应用基于源代码安全检测中,它通过符号表达式来模拟程序执行,将程序输出表示成包含这些符号的逻辑或数学表达式,从而进行语义分析。 符号执行可分为过程内分析和过程间分析(或全局分析)。...
  • 股票预测项目(在下面链接中)包含以下元素(只是数据,没有花哨CSS)。 -分析-数据科学-推荐引擎-决策预测-一点博弈论-机器学习(即将发生) 第一个选项卡...摘要分析 只需输入符号即可。 它确实根据历史...
  • 训练变压器网络以识别符号音乐中“错误”(定义为基本事实任何偏差)实验。 make_hdf5.py将.krn文件数据集处理为类似MIDI基于事件格式。 essen_meertens_songs.hdf5是使用此脚本处理过单声道民歌...
  • 数学符号的意义总结(未完待续)

    千次阅读 2017-07-31 20:11:11
    。。。同阶无穷大(无穷小) ∝正比于 ξ,ɛ,ω,ϖ,η希腊字母,纯粹变量 ...⊄,⊅,⊈,⊉不包含于,不包含 ⊊,⊋真包含于,真包含 ∈属于 ¬否 ∃存在∀任意 ∧合取 ≜定义
  • 例如,您授权API控制器可能包含INFO日志级别,其中包含有关授权成功与否用户请求授权信息。 使用INFO日志级别记录信息应纯粹是信息性,并且不定期对其进行调查不应导致丢失任何重要信息。 :warning: ...
  •  本标准适用电子工业生产中或设备上各种气体、水、油、溶液等输送管路及电气管路。  2 引用标准  下列标准所包含的条文,通过在本标准中引用而构成为本标准条文。本标准出版时,所示版本均为有效。所有...
  •  本标准适用电子工业生产中或设备上各种气体、水、油、溶液等输送管路及电气管路。  2 引用标准  下列标准所包含的条文,通过在本标准中引用而构成为本标准条文。本标准出版时,所示版本均为有效。所有...
  • Linux内核头文件提供了一个方便方法用来管理符号的对模块外部可见性,因此减少了命名空间污染(命名空间名称可能会内核其他地方定义名称冲突),并且适当信息隐藏。 如果你模块需要输出符号给其他模块使用...
  • 在笔记开始前,先声明一下:本笔记将会包含抽象代数组合数学两部分内容。其中抽象代数部分内容将比较基础(Galois理论这种就不存在了233,若之后有时间可以另行补充)。另外,假定读者都具有了集合论基本...
  • 一,运算符优先级表达式可能会包含不止一个运算符,这些不同运算先后次序就是运算符优先级。对于数学运算符来说,Python就遵循着数学上规则。(1)括号内内容最优先用括号来强制某些表达式有限计算。所以2**(3...
  • EL表达式类似,之所以能取到值,是因为OGNL把内置对象存在了值栈里。 #号 #号相当ActionContext.getContext() 因为context中对象不是root对象,所以... 包含封装了请求参数Map #parameters[0]相当...
  • 类模板是c++编译器指令 说明了如何生成类和成员函数 除非编译器实现了新关键字export关键字 否则将模板成员函数放置在一个独立实现文件中 将无法运行 因为模板不是函数 他们不能单独编译 模板必须特定模板...
  • 前言本文文字及图片来源网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。1. 换行缩进1. 1条代码为1行,例如:1个赋值、1个请求、1个运算、1个打印,结尾不需要...
  • ArcGIS Runtime SDK for iOS之符号和渲染

    千次阅读 2015-03-08 19:45:14
    本篇文章翻译自点击打开链接,有不妥之处还请大家多多指正!  符号定义了图形外观的非地理方面。它包括了图形的颜色、线宽、透明度等等。ArcGIS Runtime SDK for iOS包含了...应用每个图层的符号取决图形的属性
  • 1、在OC中,字符串常量...import用途include用途一样,但是可以防止include会多次拷贝问题。 3、NSlog();这一函数来自Foundation框架中,输出日志时会在前面显示出时间、源码文件名和代码行数,如下: 代码:
  • 该图式符号库适用ArcGIS软件平台下图件制作。 图式符号库由FHK.ttf文件和.style文件构成。其中,FHK.ttf文件包含耕地( )、园地( )、农田水利设施( )三种地类符号。.style符号库文件为每一张必备图件要素...
  •  软链接又叫符号链接,这个文件包含了另一个文件路径名。可以是任意文件或目录,可以链接不同文件系统文件。  链接文件甚至可以链接不存在文件,这就产生一般称之为"断链"问题(或曰“现象"),链接文件...
  • 因为 C 编译器编译函数时不带参数的类型信息,只包含函数的符号名字。如 void foo( int x ) , C 编译器会将此函数编译成类似 _foo 的符号,C 链接器只要找到了调用函数的符号,就会认为链接成功。而 C++ 编译器为了...
  • 发现有如下类似asp.net标识符号 软件特性: 1.他可以用于生成C#,VB.NET,TSQL以及其他任何语言代码 2.他本身是可以编程(这是他灵活性之源) 3.他提供了强大SchemaExplorer对象,使数据库储过程生成非常容易...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 911
精华内容 364
关键字:

包含与包含于的符号