我想知道,为什么MailboxProcessor处理异常的默认策略只是默默地忽略它们.例如:
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop() =
async { printfn "waiting for data..."
let! data = inbox.Receive()
failwith "fail" // simulate throwing of an exception
printfn "Got: %d" data
return! loop()
}
loop ())
()
counter.Post(42)
counter.Post(43)
counter.Post(44)
Async.Sleep 1000 |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)
没有任何反应.程序执行没有致命的停止,或者出现带有"未处理的异常"的消息框.没有.
如果有人使用PostAndReply方法,这种情况会变得更糟:结果是保证死锁.
这种行为有什么理由吗?
我有一个tableA不同的价值观:
data
------
10
15
20
40
40000
50000
60000
Run Code Online (Sandbox Code Playgroud)
此外,我需要获取有关该数据的一些统计信息(我想在一个查询中执行此操作),例如:
select count(data) from tableA where data < 100
union all
select count(data) from tableA where data >= 100
Run Code Online (Sandbox Code Playgroud)
结果,我收到了
(No column name)
----------------
4
3
Run Code Online (Sandbox Code Playgroud)
但我希望在一行中收到结果,如下所示:
Small | Big
---------
4 | 3
Run Code Online (Sandbox Code Playgroud)
怎么做?可能吗?
代码示例:
let foo1 (arr : int[]) =
for i = 0 to arr.Length-1 do
arr.[i] <- i
let foo2 (arr : int[]) =
for i in [0..arr.Length-1] do
arr.[i] <- i
Run Code Online (Sandbox Code Playgroud)
我认为这个功能应该相互对应(在性能方面).但如果我们查看IL列表,我们会看到:
第一个功能,15行,没有动态分配,没有try操作员,没有虚拟呼叫:
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0011
// loop start (head: IL_0011)
IL_0005: ldarg.0
IL_0006: ldloc.0
IL_0007: ldloc.0
IL_0008: stelem.any [mscorlib]System.Int32
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: add
IL_0010: stloc.0
IL_0011: ldloc.0
IL_0012: ldarg.0
IL_0013: ldlen
IL_0014: conv.i4
IL_0015: blt.s IL_0005
// end loop …Run Code Online (Sandbox Code Playgroud) > let a = [| 'a'..'d' |];;
val a : char [] = [|'a'; 'b'; 'c'; 'd'|]
Run Code Online (Sandbox Code Playgroud)
做琐碎的切片:
> a.[1..2], [1..2];;
val it : char [] * int list = ([|'b'; 'c'|], [1; 2])
Run Code Online (Sandbox Code Playgroud)
现在尝试使用空白区域:
> a.[1..0], [1..0];;
val it : char [] * int list = ([||], [])
Run Code Online (Sandbox Code Playgroud)
似乎工作和合理 - 我们有两个空序列.
但它失败了:
> a.[5..0];;
System.OverflowException: Arithmetic operation resulted in an overflow.
at <StartupCode$FSI_0018>.$FSI_0018.main@()
Stopped due to error
Run Code Online (Sandbox Code Playgroud)
当然,有一种解决方法[| for i in [5..0] -> a.[i] |].但我想念a.[5..0]失败的原因?为什么不直接返回空数组?这种行为有什么理由吗?
代码的一小部分,以突出问题:
open System.IO
let do_smth i (stm : #System.IO.Stream) = // val do_smth : 'a -> #Stream -> unit
(*....*)
()
type SomeOps = SomeOps with
static member op (i : int) = do_smth i
let test_currying i = do_smth i // val test_currying : 'a -> (Stream -> unit)
// NB: Stream, not #Stream
let main() =
use stm = new System.IO.MemoryStream()
test_currying 42 stm // OK, upcasted to Stream somehow
SomeOps.op 42 stm // compiler error!
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下,为什么编译器的行为在最后两行中如此不同?为什么我们#Stream …
考虑两个抽象类alpha和beta:
[<AbstractClass>]
type alpha () =
abstract member foo: beta->beta
[<AbstractClass>]
and beta () = //***
abstract member bar: alpha
Run Code Online (Sandbox Code Playgroud)
如果我尝试编译,我得到一个错误,在***指示的行上:
error FS0010: Unexpected keyword 'and' in interaction
Run Code Online (Sandbox Code Playgroud)
如果我写:
[<AbstractClass>]
type alpha () =
abstract member foo: beta->beta
and beta () =
abstract member bar: alpha
Run Code Online (Sandbox Code Playgroud)
然后我得到:
error FS0365: No implementation was given for 'abstract member beta.bar : alpha'
Run Code Online (Sandbox Code Playgroud)
以及我应该添加AbstractClass属性的提示
那么我如何声明循环定义的抽象类?
.net f# abstract-class circular-dependency circular-reference
是否有标准函数来枚举一个像Python的enumerate()一样工作的F#序列?
从头开始编写非常容易:
let enumerate (sq : seq<'T>) = seq {
let rec loop (e : IEnumerator<'T>) index = seq {
if e.MoveNext() then
yield (index, e.Current)
yield! loop e (index+1)
}
use enum = sq.GetEnumerator()
yield! loop enum 0
}
Run Code Online (Sandbox Code Playgroud)
但我不想重新发明轮子.
PS:还有,我试过了
let seasons = ["Spring"; "Summer"; "Fall"; "Winter"]
for x in Seq.zip [0..100000] seasons do
printfn "%A" x
Run Code Online (Sandbox Code Playgroud)
但这[0..10000]部分看起来很难看.
是否有可能获得"当前的类型struct" struct?例如,我想做这样的事情:
struct foobar {
int x, y;
bool operator==(const THIS_TYPE& other) const /* What should I put here instead of THIS_TYPE? */
{
return x==other.x && y==other.y;
}
}
Run Code Online (Sandbox Code Playgroud)
我试着这样做:
struct foobar {
int x, y;
template<typename T>
bool operator==(const T& t) const
{
decltype (*this)& other = t; /* We can use `this` here, so we can get "current type"*/
return x==other.x && y==other.y;
}
}
Run Code Online (Sandbox Code Playgroud)
但它看起来很难看,需要支持最新的C++标准,而MSVC不能编译它(它会因"内部错误"而崩溃).
实际上,我只是想编写一些预处理器宏来自动生成如下函数operator==:
struct foobar {
int x, …Run Code Online (Sandbox Code Playgroud) 在我们的应用程序中,我们使用Boost库(和ASIO进行网络通信).
最近,我们发现如果我们通过相同的套接字从不同的线程发送数据,我们的客户端应用程序就会接收数据.
小测试突出问题:
#include <stdio.h>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
void send_routine(boost::shared_ptr<boost::asio::ip::tcp::socket> s, char c)
{
std::vector<char> data(15000, c);
data.push_back('\n');
for (int i=0; i<1000; i++)
boost::asio::write(*s, boost::asio::buffer(&data[0], data.size()));
}
int main()
{
using namespace boost::asio;
using namespace boost::asio::ip;
try {
io_service io_service;
io_service::work work(io_service);
const char* host = "localhost";
const char* service_name = "18000";
tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), host, service_name);
tcp::resolver::iterator iterator = resolver.resolve(query);
auto socket = boost::shared_ptr<tcp::socket>(new tcp::socket(io_service));
socket->connect(*iterator);
boost::thread t1(send_routine, socket, 'A');
boost::thread t2(send_routine, socket, 'B');
boost::thread t3(send_routine, socket, …Run Code Online (Sandbox Code Playgroud)