`
凌川__
  • 浏览: 84078 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

变量一定要有类型吗(一)

阅读更多
先讨论一下Ruby是不是强类型。


1).在《Beyond Java》September 2005 一书  6.1.2节Typing  中,Bruce Tate举例
     irb(main):015:0> "fish"+4
    TypeError: cannot convert Fixnum into String
            from (irb):15:in‘+’
              from (irb):15
从而得出结论:
引用
That means Ruby is strongly typed.


我们知道,Ruby是动态语言,在运行中边解释、边检测、边执行,检测类型匹配吗?不是检测类型匹配,而是检测语法。
String类的‘+’是一个方法,但是,Ruby从来不拒绝你重写方法。
class String
  alias : old_plus :+
  def +(other)
    self.old_plus(other.to_s)    
  end  
end

puts "fish"+4       # => fish4
puts '1 ' + 2.3      # => 1 2.3



2).Bruce Tate 在“跨越边界: Java 模型以外的类型策略”2006 年 6 月 一文中写到:
引用
...这两种语言都 倾向于 强类型...


这两种语言是指Java和 Ruby,他给出了一行Ruby代码来说明;

1 + "hello"
会收到以下错误消息:
TypeError: String can't be coerced into Fixnum
        from (irb):3:in '+'
        from (irb):3


字面值1是Fixnum类的实例对象,让我们重写Fixnum类的‘+’方法,使得‘+’的语法不再出错;

class Fixnum
  alias : old_plus :+
  def +(other)
    (other.class.eql?String) ? (self.to_s << other) : (old_plus(other))    
  end  
end

puts  1 + "hello"  # => 1hello
puts  1 + " 2.3"   # => 1 2.3




3). Ruby是简单的,我们可以只管按照别人说的去使用;Ruby也是灵活而复杂的,我们可以按照自己的需求去使用;
require "another_plus3"

puts  'he'+1        # => he1
puts '1.5'+2        # => 3.5
puts 1+" he"        # => 1 he

puts 1 + " 2.3"    # => 3.3
puts 1 + 2.3      # => 3.3

puts 1.6 * "2.7"   # => 4.32
puts 1 -"2.3"    # => -1.3

类型错误根本不存在,如果语法错误算是强类型,我无言。Bruce Tate是大牛,他断言Ruby是强类型,国内的牛们也跟着如是说。
在1).中, Bruce Tate断言Ruby是强类型;
在2).中, Bruce Tate认为Ruby 倾向于 强类型。

后文“变量一定要有类型吗(二)”将更进一步说明。


#another_plus3.rb

class String

  alias : old_plus :+
  def +(other)    
    (Float(self)) + (Float(other))  rescue  (self.to_s).old_plus(other.to_s)     
  end  
  
  def coerce(other)
    case other
      when Integer : return other, Integer(self)  rescue  return Float(other), Float(self)
      when Float : return other, Float(self)
      else super
    end
  end
  
end

class Fixnum
  alias : old_plus :+
  def +(other)
    (other.class.eql?String)?(old_plus(Float(other)) rescue self.to_s<<other):(old_plus(other))      
  end  
end

class Float
  alias : old_plus :+
  def +(other)
    (other.class.eql?String)?(old_plus(Float(other)) rescue self.to_s<<other):(old_plus(other))    
  end  
end


========
题外话

假设若干年后,有一篇搜索引擎报告指出:
A)21世纪初期,网络信息以中文和英文居多;
B)其中中文信息多数是英文信息的跟风之作,
从发布时间得出,英文信息居前;
从信息不确切度得出,中文信息没有经过中文世界的思维、理解与吸收,英文信息如何错误,中文信息也有相似度极高的错误...
...

我衷心地希望与你,一起唱和出中文技术论坛自身的弦音。
分享到:
评论
6 楼 whisper 2007-03-02  
从lambda演算的角度说
我们并不关心一个东西到底是什么,而只看作一个符号
并定义符号之上的函数
然后将函数看作符号,并称为算子
在定义作用于算子上的算子,获得高阶函数

类型系统是个数学概念
咱们搞编程的明不明白不重要
5 楼 wiwolf 2007-03-01  
这个问题还需要讨论啊!...无语了...
4 楼 dustinth 2007-03-01  
假设若干年后,有一篇搜索引擎报告指出:
A)21世纪初期,网络信息以中文和英文居多;
B)其中中文信息多数是英文信息的跟风之作,
从发布时间得出,英文信息居前;
从信息不确切度得出,中文信息没有经过中文世界的思维、理解与吸收,英文信息如何错误,中文信息也有相似度极高的错误.

这真是让我喷饭, 又是"国人自强论", 鬼子们在科学技术方面的统治地位是勿庸置疑的, 不会因为我们叫口号而改变. 只有竭力追赶上咱们才有叫板的资格.
3 楼 aardvark 2007-03-01  
more:

http://en.wikipedia.org/wiki/Type_system#Strong_and_weak_typing

http://en.wikipedia.org/wiki/Comparison_of_programming_languages

2 楼 aardvark 2007-03-01  
你混淆了强类型/弱类型和静态类型/动态类型。

http://en.wikipedia.org/wiki/Strong_typing

1 楼 凌川__ 2007-03-01  
变量一定要有类型吗(二)



变量一定要有类型吗?不一定。

在《The Ruby Way 2nd》一书中,1.2.3节 Constants, Variables, and Types
“In Ruby, variables do not have types, but the objects they refer to still have types. ” 在Ruby中,变量没有类型,但变量引用的对象有类型。
1.5.2节 Perspectives in Programming
“In Ruby, variables don't have classes; only values have classes.” Ruby里, 变量没有类别;只有值才有类别。

《The Ruby Way 2nd》所描述是真的吗?口说无凭,程序为证。
a=5
puts  "a = #{a},  #{a.class}"   # => a = 5,  Fixnum

a="hh"    # a: 5 --> "hh"
puts  "a = #{a},  #{a.class}"   # => a = hh,  String

变量a只是一个符号,当a指向一个表达式的时候,那个表达式的值也许是Fixnum,也许是String。变量a并没有什么事先预定的类型;而且变量a在事后也不会固定在什么具体的类型上。
a = x==nil ? 2 : x**2 < x<<2  ? 2.0 : ""
puts a.class

你能告诉我,变量a是什么类型吗?你如果问我,我只能说:
假设x = 2,程序输出为Float;
假设x = 4,程序输出为String;
假如x 是一个无返回值的方法,程序输出为Fixnum。

Gödel在证明不完备性定理时,用一个正整数指代某个数值;用另一个正整数指代某个运算符;而且,公式也用正整数指代;定理也用正整数指代…正整数只是符号,数值、运算符、公式、定理有区别,正整数没有类型差别。

变量只是符号,变量没有类型你如果不能接受,那么,我们自小熟悉的正整数只是代表不同类事物的符号,也许会让你发疯。

完备性、一致性、可证性似乎与主题不相关,其实,计算机编程语言是形式数学的直接产物。最初的LISP语言哪里有变量类型的概念,从C一路走来,到C++,到Java,变量的概念中塞入了太多的东西。一个子类拥有许许多多的内容,它父类的父类,最初的根类,只是一个符号。

你也许认为,变量有类型拓展了我们表达事物的能力,可事实是,如今Java程序、C++程序所作的并没有超越Turing当初的构想。假如某个语言因为变量有类型而实现了智能化,请你一定,一定要mail me。

人们在编程语言的道路上行走了几十年,跌跌绊绊,缝缝补补,没能见到希望中的曙光。这一切的努力是有意义的,但也许应该回到起初的地方,认真审视,重新选择方向。Ruby是一个值得去做的尝试。

A). Rails框架充分发挥了Ruby的动态性,继承ActiveRecord时,数据库中的表将被映射为一个Ruby类,你不用操心字段值的类型。在Java及其上的框架中则作不到。

B).假设有一个Java EE 项目,几个人分别在PowerDesigner里定义了几百甚至上千张表,连接上数据库,PowerDesigner 帮你自动在库中生成了这些表;在Hibernate 里SessionFactory创建JDBC连接, MyEclipse 为你自动生成了每张表相应的JavaBean。你现在要将表中的内容显示在前端网页表格中,不是很难,可问题是,每个表有几个字段,十几个字段,甚至更多,你显示的时候不仅要考虑到getXXX(),还要顾及到返回类型,有些字段又没有定义缺省值,上万个字段实在是无休止的折磨。假设出现在生活中,你只能无奈地写一个Java类,定义成静态方法,是为了直接调用。都是类型惹得祸。
//package com.lilytech.hr.rsgl;
/*
 * Created on 2006-4-21
 *
 */

/**
 * @author Kaichuan Zhang
 *
 */
public class Wrap {
	public static String tostring(Object obj){
		try{
			return (obj!=null)?obj.toString():"";
		}catch(Exception err){
			return "";
		}	
	}
	
	public static String tostring(long obj){		
		try{
			return (new Long(obj)).toString();
		}catch(Exception err){
			return "";
		}	
	}
	
	public static String tostring(double obj){		
		try{
			return (new Double(obj)).toString();
		}catch(Exception err){
			return "";
		}	
	}
	
	public static String tostring(boolean obj){			
		try{
			return (new Boolean(obj)).toString();
		}catch(Exception err){
			return "";
		}	
	}
}

一门语言的变量有无类型,对于其上的框架之影响,如你在A). 与B).比较中所见。

结语:像Java,C++这样的静态语言需要变量有类型。而对于Ruby这样的动态语言,变量未必需要有类型。

相关推荐

    FPGA的wire和reg类型变量 fpga开发.pdf

    wire类型变量不能存储值,且必须要受到驱动器(如门或连续赋值语句)的驱动。如果没有驱动器连接到wire类型变量上,则该变量就是高阻的,即值为Z。wire类型变量常用于表示组合逻辑信号,VERILOG程序模块中的输入、...

    数据类型,常量,变量及运算符

    首先,我们要理解**数据类型**。数据类型是C语言的基础,它定义了变量能够存储的数据种类。C语言的基本数据类型包括整型(如int)、浮点型(如float和double)、字符型(如char)和布尔型(bool)。此外,还有指针、...

    如何将结构实例的结构变量转移到另一个变量组或连接中?.pdf

    WinCC的变量管理器中有一个称为“结构变量”的功能,允许用户通过图形化界面定义结构变量的成员变量和数据类型。创建结构变量后,我们可以将这个结构变量分配给一个或多个变量组或连接。 如果要将结构变量从一个...

    python变量以及数据类型

    str1 = "有喜欢的人一定要表白~你丑没关系,万一她瞎呢?" print(str1) ``` 此外,Python 还支持同时为多个变量赋相同的值,例如: ```python str1 = str2 = -1000 print(str1, type(str1), id(str1)) print(str2, ...

    C语言数据类型和变量ppt课件.ppt

    在数学中,我们对变量的概念有一定的了解和认识,如y=x2,其中x是自变量,y是因变量。在计算机中,变量是一个存储器中的存储空间,可以存储不同的数据类型,如整数、字符、浮点数等。 2. 变量的概念 一个变量就是...

    在对话框上增加编辑框,并关联控制类型的变量

    本篇将详细介绍如何在对话框上增加编辑框并关联控制类型的变量。 首先,我们需要创建一个对话框资源。在VC++的ResourceView中,选择"Dialog"类型,然后右键点击新建一个IDD_DLGTEST类型的对话框。在对话框的设计...

    C#基础变量与数据类型的文档

    本文档聚焦于C#的基础变量与数据类型,这是学习任何编程语言的第一步,也是构建强大程序的基石。 1. 变量:在C#中,变量可以被视为存储数据的容器。每当你需要在程序中存储一个值时,就需要声明一个变量。声明变量...

    全局变量、局部变量、静态变量即内存管理

    变量类型是编程语言中非常重要的一个概念,全局变量、局部变量、静态变量都是程序员经常使用的变量类型,但是这些变量类型之间的区别和联系却经常让人感到困惑。今天我们将详细地探讨这些变量类型之间的区别和联系,...

    【060期】李克特量表的变量属于顺序变量,为什么可以当作连续变量使用?.docx

    顺序变量作为分类变量的一种,能够表现出一定的顺序或等级,例如教育程度中的“小学”、“中学”、“大学”等。名义变量则不具有顺序意义,只是用来区分不同的事物或特征,如血型。 李克特量表的变量类型从本质上来...

    VB 动态变量举例

    在VB(Visual Basic)编程语言中,动态变量是一种在运行时声明和使用的变量,与静态变量相比,它们不需要在程序的开头就明确声明其类型和名称。动态变量的使用为程序员提供了更大的灵活性,使得代码更加适应多变的...

    c语言中全局变量和局部变量的探讨

    然而,对于初学者来说,掌握C语言的一些核心概念仍然存在一定的难度,尤其是在处理函数的递归调用、局部变量与全局变量的区别以及指针的使用等方面。本文旨在深入探讨C语言中的局部变量和全局变量,通过具体的例子和...

    Python变量声明:动态类型与灵活赋值的探索之旅

    Python,作为一种动态类型的编程语言,其变量声明的方式与其他静态类型语言有着显著的不同。在Python中,变量的声明不需要指定数据类型,这为开发者提供了极大的灵活性。本文将深入探讨Python中的变量声明,包括其...

    C++编程变量命名规范

    这种命名方式有助于区分成员变量与类的其他成员(如方法等)。 **示例:** ```cpp class Document { public: void PrintInfo() { std::cout ; std::cout ; } private: std::string m_DocName = "Untitled"; //...

    Python 变量类型、标准数据类型.docx

    Python 是一种动态类型的语言,它的变量类型是在运行时根据赋值自动确定的。变量是程序中存储信息的容器,它们可以存储各种不同类型的值,如整数、浮点数、字符串、列表、字典等。在Python中,创建变量并不需要预先...

    变量与基本数据类型PPT学习教案.pptx

    变量名必须遵循一定的规则,只允许包含字母、数字和下划线,并且第一个字符不能是数字。标识符是区分大小写的,因此"sum"和"SUM"是两个不同的变量。 在C++中,整型数据是最常见的数据类型之一,它们用于存储整数。...

    uboot环境变量设置方法

    U-Boot 环境变量设置方法 在 U-Boot 中,环境变量扮演着至关重要的角色,它可以由用户自己定义,但也有...但是,需要注意的是,在设置环境变量时,一定要遵守 U-Boot 的规则和约定俗成的变量名,否则可能会导致错误。

    C语言基础篇:变量和数据类型

    类型转换则是将一种数据类型转换为另一种,这在处理不同数据类型的变量相加或比较时尤其有用。例如,如果需要将一个int和一个float相加,可能需要将int转换为float。 输入输出函数`scanf()`和`printf()`是C语言的...

    第2章 变量和基本类型1

    在进行数学运算时,不同类型的变量会根据需要进行类型转换,例如,较小的类型会自动转换为较大的类型,有符号类型会转换为无符号类型。但是,如果无符号类型在运算中变成了负值,其结果可能会产生未定义的行为。 ...

    stm32 volatile变量的正确使用

    在C语言中,`volatile`是一个类型限定符,用于告知编译器不要对该变量进行优化,因为它可能在任何时候被未知的外部源更改。当一个变量被声明为`volatile`时,编译器会假设它的值可能在任意时间发生变化,因此每次...

    JavaScript:变量与数据类型

    JavaScript是一种动态类型的语言,这意味着变量的类型可以在程序运行时发生变化。例如,一个变量最初可以存储一个字符串,随后可以在程序的其他部分将其改为存储一个数字。 **1.2 变量的命名规则** - **命名规则**...

Global site tag (gtag.js) - Google Analytics