首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >T隐式转换/重载解析是如何工作的?

T隐式转换/重载解析是如何工作的?
EN

Stack Overflow用户
提问于 2016-01-28 09:27:31
回答 2查看 210关注 0票数 2

我一直在玩T,试图理解隐式转换和重载解析规则,但不知怎么的,它似乎有点奇怪……

上下文:

基本上,后者告诉您abs将在int、浮点、十进制等方面工作。因此,让我们看看它是如何工作的:

代码语言:javascript
复制
declare @foo2 sql_variant;
set @foo2 = abs(4);
select sql_variant_property(@foo2, 'BaseType')

-- result: int. OK, apparently we have an int overload. As expected.

declare @foo2 sql_variant;
set @foo2 = abs(cast(4.0 as float));
select sql_variant_property(@foo2, 'BaseType')

-- result: float. OK, apparently we have a float overload. As expected.

现在,根据隐式类型转换表,我们可以隐式转换内容。我们将通过将var二进制转换为int来检查这一点,这应该根据类型优先规则进行:

代码语言:javascript
复制
declare @foo varbinary(4);
set @foo = cast(4 as varbinary(4));
select @foo + 2;

-- result: int. OK, as expected.

从这一结果来看,我希望以下内容也能发挥作用:

代码语言:javascript
复制
declare @foo varbinary(4);
set @foo = cast(4 as varbinary(4));
select abs(@foo);
-- result: error: Operand type clash: varbinary is incompatible with float

我不明白的东西(问题):

  • 为什么隐式转换会选择'abs‘的'float’重载?这只是随机超载吗?或者是优先级列表中最高的重载(碰巧是“浮动”)?
  • 为什么不从var二进制-> int应用隐式转换?毕竟,这是一个完全有效的转换。
EN

回答 2

Stack Overflow用户

发布于 2016-01-28 12:24:05

来自MSDN的Abs:

代码语言:javascript
复制
Arguments

numeric_expression

    Is an expression of the exact numeric or approximate numeric data type category.

我猜想,调用Abs( varbinary )将尝试将var二进制转换为精确的数字或近似数字数据类型。

浮点数位于这些类型的数据类型优先级的顶部,所以我猜存在一个问题。

用我的逻辑更新

代码语言:javascript
复制
declare @foo varbinary(4);

声明变量变量。

代码语言:javascript
复制
set @foo = cast( 4 as varbinary(4));

通过执行从int到var二进制的显式强制转换,将一个值设置为此变量,这是完全可行的。

代码语言:javascript
复制
select sql_variant_property(@foo, 'BaseType')

这表明变量是varbinary类型的。

代码语言:javascript
复制
select abs(@foo);

尝试在var二进制文件上运行abs。错误信息是明确的:

代码语言:javascript
复制
Operand type clash: varbinary is incompatible with float

因此,我的猜测是abs试图将varbinary隐式转换为中的第一个,以获得精确的数值或近似数字数据类型,即浮点数。

根据CAST and CONVERT图表,此转换失败。

票数 1
EN

Stack Overflow用户

发布于 2016-01-28 12:26:34

我希望我做得对!感谢你的评论。

您已经找到了转换和优先级MSDN页面,因此让我们来看看您的示例。

代码语言:javascript
复制
declare @foo varbinary(4);
set @foo = cast(4 as varbinary(4));

福是什么类型的?

代码语言:javascript
复制
SELECT SQL_VARIANT_PROPERTY(@foo,'BaseType')

--------
varbinary

到目前为止还不错。但在@foo里有什么?

代码语言:javascript
复制
SELECT @foo
----------
0x00000004

现在,ABS()接受一个numeric --一个浮点数:

4.00相比,4是什么样子的?让我们试试:

代码语言:javascript
复制
SELECT  CONVERT(VARBINARY(MAX), 4.00) ,CONVERT(VARBINARY(MAX), 4);
------------------   -----------------------
0x0302000190010000   0x00000004

看到4.00的内部表示与4不同吗?它存储的是精度、比例尺和值,而您的“int in a var二元”则不是。

这就是转换失败的原因。ABS()接受一个numeric,您的“错误格式”varbinary不能被胁迫到一个numeric,因为它不是一个,它是一些其他的表示--我们知道它表示一个int,但是Server没有。

如果要将浮点数添加到“在”变量二进制文件中的int中,则必须执行以下操作

代码语言:javascript
复制
select CONVERT(INT, @foo) + 2.0

回到你的例子:

代码语言:javascript
复制
declare @foo varbinary(max);
set @foo = cast(4.00 as varbinary(max));
SELECT ABS(@foo+2.0)
----------
6.0

4.00以正确的内部格式转换为varbinary,并通过ABS()调用高兴地强制转换为numeric。快乐的日子。

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

https://stackoverflow.com/questions/35057532

复制
相关文章

相似问题

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