Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >两个同名的类型参数

两个同名的类型参数
EN

Stack Overflow用户
提问于 2010-09-20 13:18:50
回答 4查看 1.2K关注 0票数 6

我想知道为什么根据下面的例子,允许两个类型参数(名为"A")具有相同的名称("A")。我知道这是一个糟糕的类型参数命名,请不要这样做。

(我的猜测是它们在不同的作用域级别上,例如类级别和函数级别,并且编译器使用了某种名称混乱)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class  MyTest[A](){
    type MyType  = A

    def checkString[A](value:A, x:MyType):A = { 
       value match {
         case x:String => println("Value is a String")
         case _ => println("Value is not a String")
       }

       x match {
          case x:String => println("x is a String")
          case _ => println("x is not a String")
       }

       value
   }
}

2.8.0的输出示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest@308ff65f

scala> test.checkString("String",1)
Value is a String
x is not a String
res7: java.lang.String = String

scala> test.checkString(1,1)
Value is not a String
x is not a String
res8: Int = 1
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-09-20 15:52:00

Scala中的嵌套作用域可以自由地隐藏彼此的符号表。类型并不是你唯一能做的事情。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class X[A](a: A) {
  def X[A](a: A) {
    if (a==this.a) {
      val X = Some(this.a)
      X match {
        case Some(a) => "Confused much yet?"
        case _ => "Just because you can do this doesn't mean you should."
      }
    }
  }
}

其原则是作用域可以控制其名称空间。如果您愚蠢地使用它,这是有危险的(例如,我用Xa表示三个不同的东西,A表示两个--实际上,您可以用X替换除Some中必须为小写的标识符之外的所有标识符)。但在编写函数式代码时,它也有好处--您不必担心因为碰巧将其放在不同的上下文中而不得不重命名某个迭代变量或类型或其他任何东西。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def example = {
  val a = Array(1,2,3,4,5)
  val sumsq = a.map(i => i*i).sum
  a.map(i => {
    val a = Array.range(1,i)
    val sumsq = a.map(i => i*i).sum  // Cut and paste from above, and works!
    sumsq + i
  }).sum
}

所以,要意识到你有迷惑自己的能力,明智地选择不迷惑地使用这种能力。

票数 8
EN

Stack Overflow用户

发布于 2010-09-20 15:04:43

我不是Scala专家,但是您的代码的行为完全符合我的期望。

首先,您需要知道方法的类型参数不需要绑定到类。

例如,下面是有效的Scala。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Test1 {
    def test[A] (x: A) = println(x)
}

下面也是一个有效的Scala代码,唯一不同的是这个代码根本不使用类型A。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Test2[A] {
    def test (x: Int) = println(x)
}

所以我认为现在很清楚了,首先你创建了一个MyTestInt的实例,这是很好的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest@308ff65f

然后,在没有提供类型参数A的情况下调用checkStringA,Int,因为它是一个泛型函数,编译器必须推断A是什么类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scala> test.checkString("String",1)
Value is a String
x is not a String
res7: java.lang.String = String

注意:

在这个时间点上,Scala已经知道x必须是一个整数,并且它的类型是固定的,因为它是由MyTestInt提供的。因此,下面的代码将产生编译错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scala> val t = new MyTest[Int]
t: MyTest[Int] = MyTest@cb800f

scala> t.checkString ("A", "B")
<console>:8: error: type mismatch;
 found   : java.lang.String("B")
 required: t.MyType
       t.checkString ("A", "B")

现在编译器查看您提供的参数,并发现它是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
checkString ("String", 1)

它对应于

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
checkString (value: A, x: Int)

所以现在编译器知道了checkStringA中的类型A,Int必须是一个字符串,如果你手工完成所有这些操作,你的代码将如下所示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest@5bda13

scala> test.checkString[String]("String", 1)
Value is a String
x is not a String
res1: String = String

scala> test.checkString[Int] (3, 4)
Value is not a String
x is not a String
res4: Int = 3

scala> test.checkString[Int] ("String", 4)
<console>:8: error: type mismatch;
 found   : java.lang.String("String")
 required: Int
       test.checkString[Int] ("String", 4)
                          ^    
票数 4
EN

Stack Overflow用户

发布于 2010-09-20 13:50:21

嗯,我相信在scala中我们使用与Java相同的规则,基本上我们在寻找Java中最小的可用范围:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo<T>{
   T instance;

   void <T> T getInstance(){
       return instance
    }
}

将产生编译错误,因为泛型方法getInstance中声明的类型T与类Foo的参数类型不同。在Scala的情况下,我相信您会这样写

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def checkString[A]

你告诉编译器,函数的行为会因提供的类型而异,但它与外部类的参数类无关。不幸的是,我现在找不到正确的地方是Scala规范。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3751823

复制
相关文章
4.《python自省指南》学习
  前面几篇博客我都是通过python自省来分析代码并试图得出结论。当然,仅仅通过自省能解决的问题有限,但遇到问题还是不自主的去用这个功能,觉得对于认识代码的含义还是有一定帮助的。而这些自省的知识我都是从python自省指南中学习的。所以,下文的内容基本参考自这份指南,看官可以直接转跳,笔者只是希望通过博客整理自己的思路,检验学习效果。
py3study
2020/01/20
6880
python sys.stdout
下面介绍几个我们经常不经意就会用到的sys包的命令 stdout/stderr/stdin
kirin
2020/10/27
9750
Python中os与sys两模块的区别 原
os: This module provides a portable way of using operating system dependent functionality.
晓歌
2018/08/15
4890
python 重定向输入输出流 脚本
file-like objects that save standard output text in a string and provide
用户5760343
2022/05/13
6460
python标准输入输出
sys.stdin与可读文件对象具有相同的类型,sys.stdout与可写文件对象具有相同的类型
py3study
2020/01/08
8620
Python unittest 测试输入(input)和输出(print)
测试输入输出的解决方法是: 将标准输入输出定向到一个StringIO类(python3是 io.StringIO)。
饶文津
2020/05/31
1.7K0
【Python】重定向 Stream 到
Python 系统模块 sys 中有三个变量 stdin 、 stdout 与 stderr ,分别对应标准输入流、输出流与错误流。stdin 默认指向键盘, stdout 与 stderr 默认指向控制台。
py3study
2020/01/17
9010
AttributeError: 'dic
这是因为换成了Python3.6.5,Python3.6.5已经删除了has_key()方法,改成了下面的写法:
py3study
2020/01/19
6150
2018年8月25日python中os模块和sys模块的区别
    os: This module provides a portable way of using operating system dependent functionality.
武军超
2018/09/27
8640
Python中标准输入(stdin)、标准输出(stdout)、标准错误(stdout)的用法
Python 3.x 中 input() 函数可以实现提示输入,python 2.x 中要使用 raw_input(),例如:
Python学习者
2023/08/01
4310
Python 代码片段总结
生成的pyc可以跨平台使用,但是只能这样用python xxx.pyc,而不能使用./xxx.pyc执行,因为缺少了shebang的支持,不过貌似Binfmt_misc可以解决这个问题,ubuntu下apt-get install binfmt-support可以直接安装。
老高的技术博客
2022/12/28
6120
Python 代码片段总结
python中的sys模块函数
Sys模块函数之多,我只能选取自己认为比较实用的一些函数列在此处。借马云找员工的说法,”找最合适的而不是最天才的”,这句话,我个人觉得在很多方面都能适应,学习也不在话下。Sys模块功能的确很多,但我们应该将重点放在那些功能才是最适合我们的,为此,我列的这些函数,就是我认为比较适合我以后开发的函数。 (1)sys.argv 很多人会想,我如何给我的程序在外部传递参数呢?这个,就可以实现。如: Tesy.py Import sys Print sys.argv[number] 一般情况下,number为0是这个脚本的名字,1,2…则为命令行下传递的参数.如: Test.py脚本内容: import sys
全栈程序员站长
2022/09/09
9470
python模块—command and
  返回结果是一个tuple元组,第一个值为接收状态码,int类型,0表示正常,非0表示异常;第二个值为字符串,即shell命令执行的结果
py3study
2020/01/08
4950
解决jupyter控制台出现中文乱码的问题
前几天在Python钻石交流群【盼头】问了一道Jupyter乱码处理的问题,如下图所示。
前端皮皮
2022/08/17
1.6K0
解决jupyter控制台出现中文乱码的问题
了解和分析iOS Crash Report
翻译自苹果官方文档:Understanding and Analyzing Application Crash Reports
nimomeng
2018/09/13
1.7K0
了解和分析iOS Crash Report
实现一个 BrainFuck 解释器
BrainFuck是一门非常简单的图灵完备的编程语言,只有 8 个指令: Brainfuck 包含一个有 30,000 个单元为 0 的数组,和一个数据指针指向当前的单元。
杜逸先
2023/04/13
6610
Python教程:sys.stdout方法
Python中sys 模块中的一个方法是stdout ,它使用其参数直接显示在控制台窗口上。
Python学习者
2023/10/23
4190
实现一个Brainfuck解释器
Brainfuck 包含一个有 30,000 个单元为 0 的数组,和一个数据指针指向当前的单元。
杜逸先
2023/04/06
5990
点击加载更多

相似问题

Odoo 12:'report.label.report_label‘AttributeError

116

AttributeError:“”ca.report“”对象没有属性“”appliquer“”

122

Input、sys.stdin和functions

110

使用sys.stdin

114

Pandas-分析错误AttributeError:'DataFrame‘对象没有属性'profile_report’

84
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文