首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >你的情商怎么样?拍球拍?

你的情商怎么样?拍球拍?
EN

Stack Overflow用户
提问于 2013-07-10 13:40:47
回答 2查看 1.6K关注 0票数 8

在我的大学里,我们不得不与球拍合作,因为我有点喜欢它,我买了最近出版的书“球拍领域”从没有淀粉。

但是,到目前为止,我还不知道它们在第四章中的意思是什么,当他们试图解释eq的时候?作品:

  1. 首先,他们解释了如何平等?比较两个值是否由相同的部分组成。好吧,没问题,我明白了:平等?做的事情和Java的相等(SomeObject)方法几乎是一样的。如果两个对象/结构/任何内容相同,则返回#t。
  2. 然后,我想,艾克?必须与Java的==操作符等效,后者不按内容进行比较,而是基于引用。
  3. 这种想法似乎被书中的下列句子所证实:"eq?比较一种结构是否改变了另一种结构.“太棒了!让我们将其与以下Java代码进行比较: 点p1 =新点(5,5);点p2 = p1;System.out.println(p1 == p2);// true,因为引用已被复制。System.out.println( p1.x );// 5 System.out.println(p2.x);// 5p1.x= 42;System.out.println(p1.x);// 42 System.out.println(p2.x);//相应地,42 让我们试试这个球拍: (定义cons1 (cons1空))(定义cons2 cons1) (eq?#t,因为引用已被复制。(就位!cons1 (cons2空) cons1 ;;返回'(2) -正如预期的那样。仍然返回'(1)。 为什么?cons2指向cons1,它本身指向'(2)。此外,他们不是刚刚说,他们是平等的,只要一个改变另一个?

显然,现在我不明白为什么这不像预期的那样,正因为如此,我看不出什么方程?在做什么。也许我错了,这和推荐信没有任何关系.

如果有人知道这一点,请分享你的智慧;)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-10 13:50:57

有关eq?如何工作的技术解释,请看一下当前的规格说明,您将找不到更详细的参考资料。或者简单的检查球拍的文档关于这个主题,特别是程序eq?eqv?equal?。关于您的问题--结果和预期的一样,在Scheme代码中是正确的,让我们来看看为什么。注意,在Java的这一行中:

代码语言:javascript
复制
p1.x = 42;

您正在修改p1p2都指向的同一个对象。鉴于在这一行:

代码语言:javascript
复制
(set! cons1 (cons 2 empty))

您正在创建一个新的、不同的对象,并将cons1设置为指向它,但是cons2仍然指向旧对象。您可以确认这一点,在上一行之后,比较(eq? cons1 cons2)将返回#f

关键是:这些例子是不对等的。Java示例处理两个不同引用指向的单个对象,而Scheme示例处理两个对象和两个引用。

为了比较起见,下面是一个类似于Java代码的Scheme示例,它的工作方式与您预期的一样,因为在这里,我们修改了一个由两个引用指向的单个可变对象:

代码语言:javascript
复制
#lang racket
(require scheme/mpair) ;; `m` stands for "mutable"

(define p1 (mlist 5 5))
(define p2 p1)

(eq? p1 p2)       ;; #t
(mcar p1)         ;;  5
(mcar p2)         ;;  5

(set-mcar! p1 42)
(eq? p1 p2)       ;; #t
(mcar p1)         ;; 42
(mcar p2)         ;; 42
票数 8
EN

Stack Overflow用户

发布于 2013-07-10 16:14:53

阿:你想确保你在改变结构。在您的示例中,它实际上不是改变现有值的结构,而是构造一个全新的值并将cons1指向它。您的概念是正确的:eq?基本上是==

简单地说,这是Java表单中的错误,您可以看到哪里出了问题:

代码语言:javascript
复制
int[] lst1 = new int[] { 1 };       // (define cons1 (cons 1 empty))
int[] lst2 = lst1;                  // (define cons2 cons1)
System.out.println(lst1 == lst2);   // (eq? cons1 cons2)
lst1 = new int[] { 2 };             // (set! cons1 (cons 2 empty))
System.out.println(lst1[0]);        // (list-ref cons1 0)
System.out.println(lst2[0]);        // (list-ref cons2 0)

实际上,在这一点上,您需要检查eq?-ness的末尾:您将看到这两个值不再是eq?:它们是两个不同的值。

您真正想要的是在结构上执行突变,而不是变量重新绑定。在Racket中,由于列表是不可变的,所以您需要使用允许变异的不同数据结构。向量是一个可以演示的示例数据类型。让我们再来一次“罗塞塔”,这样你就可以看到这个比喻了:

代码语言:javascript
复制
(define vec1 (vector 1))          ;; int[] vec1 = new int[] { 1 };
(define vec2 vec1)                ;; int[] vec2 = vec1;
(eq? vec1 vec2)                   ;; System.out.println(vec1 == vec2);
(vector-set! vec1 0 2)            ;; vec1[0] = 2;
(vector-ref vec1 0)               ;; System.out.println(vec1[0]);
(vector-ref vec2 0)               ;; System.out.println(vec2[0]);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17572181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档