Scala,C#等效于F#活动模式
F#具有一项功能,允许用户扩展模式匹配:Scala,C#等效于F#活动模式,c#,scala,f#,C#,Scala,F#,F#具有一项功能,允许用户扩展模式匹配: let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd match 3 with | Odd -> printfn "odd" | Even -> printfn "even" 或: 神奇之处在于ParseRegex模式,其定义如下: (** Definition of the MatchRegex active pattern *) let (|ParseRege
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd
match 3 with | Odd -> printfn "odd"
| Even -> printfn "even"
或:
神奇之处在于ParseRegex模式,其定义如下:
(** Definition of the MatchRegex active pattern *)
let (|ParseRegex|_|) rgx s = match Regex(rgx).Match(s) with
| m when not m.Success -> None
| m -> Some(List.tail [for x in m.Groups->x.Value])
ParseRegex现在可以在任何地方使用,其要点是可以以非常简洁的方式解析字符串的各个部分
Scala有类似的特性吗
在C语言中,这种简洁程度似乎很难实现,但也许一些使用隐式转换的巧妙技巧会有所帮助?您可以通过一个名为的scala功能来实现这一功能 对于偶数/奇数示例:
object Even {
def unapply(x:Int) = if (x % 2 == 0) Some(x) else None
}
object Odd {
def unapply(x:Int) = if (x % 2 == 1) Some(x) else None
}
3 match {
case Even(x) => println("even")
case Odd(x) => println("odd")
}
免责声明:我不知道F
在scala中,如果一个值有一个名为unapply(或unapplySeq)的方法,那么它将用于模式匹配
取消应用的定义是:
object Example {
def unapply(t: T): Option[(T1, ..., Tn)] = ...
}
如果返回None
,则表示不匹配,Some((t1,…,tn))
表示匹配成功,并且可以绑定到值t1到tn
然后它可以用作:
value match {
case Example(t1, ..., tn) => ...
}
如果匹配可以有动态数量的结果,则使用unplyseq
,返回选项[List[T]]
最后,如果匹配时不需要绑定变量,unapply可以只返回一个布尔值
示例:
val Date = ""(\d{1,2})/(\d{1,2})/(\d{1,2})$".r
"12/12/12" match {
case Date(m, d, y) => ...
}
.r
方法将字符串转换为正则表达式。该类有一个unallyseq方法,该方法与正则表达式中的组相匹配
case class Person(name: String, age: Int)
somePerson match {
case Person(name, age) => ...
}
在本例中,语法case类
使用与构造函数参数匹配的unapply方法创建具有相同名称(Person)的单例对象
更新:下面是如何定义偶数和奇数
首先是一些概括。偶数和奇数都可以通过函数表示,但是我们需要使这个函数符合提取器规范,也就是说,通过unapply应用它
class BooleanExtractor[T](f: T => Boolean) {
def unapply(t: T) = f(t)
}
现在,我们可以这样使用(显示两种方式)
和使用:
scala> 3 match {
| case Even() => println("even")
| case Odd() => println("odd")
| }
odd
您可以在Scala中实现同样的效果。这个概念被称为提取器。定义它们的语法似乎比F#中的要难看一些。我将提供第一个示例:
scala> object Even {def unapply(z: Int) = (z%2 == 0)}
defined module Even
scala> object Odd {def unapply(z: Int) = (z%2 != 0)}
defined module Odd
scala> 2 match {
| case Even() => "even";
| case Odd() => "odd";
| }
res10: java.lang.String = even
你的第二个例子也有效。必须从unapply方法返回DateTime对象。我提供了一个链接,您可以在其中阅读更多有关该主题的内容。我注意到没有人为此添加C#代码,因此我尝试在这里复制代码中的功能: 基本上,我创建了一个或两个助手类,然后可以编写如下代码:
var apInt = Option<int>.From<string>(s =>
{
int i;
return System.Int32.TryParse(s, out i)
? new Option<int>(i)
: Option<int>.Empty;
});
var apBool = Option<bool>.From<string>(s =>
{
bool b;
return System.Boolean.TryParse(s, out b)
? new Option<bool>(b)
: Option<bool>.Empty;
});
var testParse = new Action<string>(s =>
{
FluidFunc
.Match(s)
.With(apInt, r => Console.WriteLine($"The value is an int '{r}'"))
.With(apBool, r => Console.WriteLine($"The value is an bool '{r}'"))
.Else(v => Console.WriteLine($"The value '{v}' is something else"));
});
testParse("12");
testParse("true");
testParse("abc");
var-apInt=Option.From(s=>
{
int i;
返回系统.Int32.TryParse(s,out i)
?新方案(i)
:选项。空;
});
var apBool=Option.From(s=>
{
布尔b;
返回系统.Boolean.TryParse(s,out b)
?新方案(b)
:选项。空;
});
var testParse=新操作=>
{
FluidFunc
.比赛
.With(apInt,r=>Console.WriteLine($“该值是一个int'{r}'))
.With(apBool,r=>Console.WriteLine($“值是bool'{r}'))
.Else(v=>Console.WriteLine($“值“{v}”是其他内容”);
});
testParse(“12”);
testParse(“真”);
测试解析(“abc”);
doh,在发布之前我也刷新了。谢谢!所有的安瓦尔人都很好。我接受这个,因为我从中学到了很多。这很好,但我可以把它们结合起来。例如case Even()&&produceOftree(),因此在本例中6可能是第一个true,然后是Scala中的12个ect?提取器。C#甚至没有可比性,它甚至没有模式匹配。。。
scala> object Even {def unapply(z: Int) = (z%2 == 0)}
defined module Even
scala> object Odd {def unapply(z: Int) = (z%2 != 0)}
defined module Odd
scala> 2 match {
| case Even() => "even";
| case Odd() => "odd";
| }
res10: java.lang.String = even
var apInt = Option<int>.From<string>(s =>
{
int i;
return System.Int32.TryParse(s, out i)
? new Option<int>(i)
: Option<int>.Empty;
});
var apBool = Option<bool>.From<string>(s =>
{
bool b;
return System.Boolean.TryParse(s, out b)
? new Option<bool>(b)
: Option<bool>.Empty;
});
var testParse = new Action<string>(s =>
{
FluidFunc
.Match(s)
.With(apInt, r => Console.WriteLine($"The value is an int '{r}'"))
.With(apBool, r => Console.WriteLine($"The value is an bool '{r}'"))
.Else(v => Console.WriteLine($"The value '{v}' is something else"));
});
testParse("12");
testParse("true");
testParse("abc");