Interactive Extensions(Ix)

本文的主题为对 Ix 库,对 LINQ 的扩展。

Buffer

Ix.NET Buffer

Ix.NET BufferTest

Buffer 方法将源序列按照起始位置和元素个数分成若干组,形成序列的序列。

var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(3).ToList();
// res.Count == 4
// res[0] == { 0, 1, 2 }
// res[1] == { 3, 4, 5 }
// res[2] == { 6, 7, 8 }
// res[3] == { 9 }
var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(5).ToList();
// res.Count == 2
// res[0] == { 0, 1, 2, 3, 4 }
// res[1] == { 5, 6, 7, 8, 9 }
var rng = Enumerable.Empty<int>();
var res = rng.Buffer(5).ToList();
// res.Count == 0
var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(3, 2).ToList();
// res.Count == 5
// res[0] == { 0, 1, 2 }
// res[1] == { 2, 3, 4 }
// res[2] == { 4, 5, 6 }
// res[3] == { 6, 7, 8 }
// res[4] == { 8, 9 }
var rng = Enumerable.Range(0, 10);
var res = rng.Buffer(3, 4).ToList();
// res.Count == 3
// res[0] == { 0, 1, 2 }
// res[1] == { 4, 5, 6 }
// res[2] == { 8, 9 }

Case

Ix.NET Case

Ix.NET CaseTest

Case 方法根据回调函数的结果选择并返回 Dictionary 参数中的序列。

var x = 1;
var d = 'd';
var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
{
{ 0, new[] { 'a' } },
{ 1, new[] { 'b' } },
{ 2, new[] { 'c' } },
{ 3, EnumerableEx.Defer(() => new[] { d }) },
});
// res.Single() == 'b'
// res.Single() == 'b'
x = 0;
// res.Single() == 'a'
x = 2;
// res.Single() == 'c'
x = 3;
// res.Single() == 'd'
d = 'e';
// res.Single() == 'e'
x = 4;
Assert.True(res.IsEmpty());
var x = 1;
var d = 'd';
var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
{
{ 0, new[] { 'a' } },
{ 1, new[] { 'b' } },
{ 2, new[] { 'c' } },
{ 3, EnumerableEx.Defer(() => new[] { d }) },
}, new[] { 'z' });
// res.Single() == 'b'
// res.Single() == 'b'
x = 0;
// res.Single() == 'a'
x = 2;
// res.Single() == 'c'
x = 3;
// res.Single() == 'd'
d = 'e';
// res.Single() == 'e'
x = 4;
// res.Single() == 'z'

Catch

Ix.NET Catch

Ix.NET CatchTest

var ex = new MyException();
var res = EnumerableEx.Throw<int>(ex).Catch<int, MyException>(e => { Assert.Same(ex, e); return new[] { 42 }; }).Single();
// res == 42
var ex = new MyException();
var res = EnumerableEx.Throw<int>(ex).Catch<int, Exception>(e => { Assert.Same(ex, e); return new[] { 42 }; }).Single();
// res == 42
var ex = new MyException();
AssertThrows<MyException>(() =>
{
EnumerableEx.Throw<int>(ex).Catch<int, InvalidOperationException>(e => { Assert.True(false); return new[] { 42 }; }).Single();
});
var xs = Enumerable.Range(0, 10);
var res = xs.Catch<int, MyException>(e => { Assert.True(false); return new[] { 42 }; });
// res == xs
var xss = new[] { Enumerable.Range(0, 5), Enumerable.Range(5, 5) };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 5)
var xss = new[] { Enumerable.Range(0, 5), Enumerable.Range(5, 5) };
var res = xss.Catch();
// res == Enumerable.Range(0, 5)
var xss = new[] { Enumerable.Range(0, 5), Enumerable.Range(5, 5) };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 5)
var xss = new[] { Enumerable.Range(0, 5).Concat(EnumerableEx.Throw<int>(new MyException())), Enumerable.Range(5, 5) };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 10)
var xss = new[] { Enumerable.Range(0, 5).Concat(EnumerableEx.Throw<int>(new MyException())), Enumerable.Range(5, 5) };
var res = xss.Catch();
// res == Enumerable.Range(0, 10)
var xss = new[] { Enumerable.Range(0, 5).Concat(EnumerableEx.Throw<int>(new MyException())), Enumerable.Range(5, 5) };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 10)
var e1 = new MyException();
var ex1 = EnumerableEx.Throw<int>(e1);
var e2 = new MyException();
var ex2 = EnumerableEx.Throw<int>(e2);
var e3 = new MyException();
var ex3 = EnumerableEx.Throw<int>(e3);
var xss = new[] { Enumerable.Range(0, 2).Concat(ex1), Enumerable.Range(2, 2).Concat(ex2), ex3 };
var res = xss.Catch();
var e = res.GetEnumerator();
HasNext(e, 0);
HasNext(e, 1);
HasNext(e, 2);
HasNext(e, 3);
AssertThrows<MyException>(() => e.MoveNext(), ex => ex == e3);
var xs = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var res = xs.Catch<int, MyException>(e => { Assert.False(true); return new[] { 42 }; });
// res == xs
var xss = new[] { new[] { 0, 1, 2, 3, 4 }, new[] { 5, 6, 7, 8, 9 } };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 5)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }, new[] { 5, 6, 7, 8, 9 } };
var res = xss.Catch();
// res == Enumerable.Range(0, 5)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }, new[] { 5, 6, 7, 8, 9 } };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 5)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }.Concat(EnumerableEx.Throw<int>(new MyException())), new[] { 5, 6, 7, 8, 9 } };
var res = EnumerableEx.Catch(xss);
// res == Enumerable.Range(0, 10)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }.Concat(EnumerableEx.Throw<int>(new MyException())), new[] { 5, 6, 7, 8, 9 } };
var res = xss.Catch();
// res == Enumerable.Range(0, 10)));
var xss = new[] { new[] { 0, 1, 2, 3, 4 }.Concat(EnumerableEx.Throw<int>(new MyException())), new[] { 5, 6, 7, 8, 9 } };
var res = xss[0].Catch(xss[1]);
// res == Enumerable.Range(0, 10)));
var e1 = new MyException();
var ex1 = EnumerableEx.Throw<int>(e1);
var e2 = new MyException();
var ex2 = EnumerableEx.Throw<int>(e2);
var e3 = new MyException();
var ex3 = EnumerableEx.Throw<int>(e3);
var xss = new[] { new[] { 0, 1 }.Concat(ex1), new[] { 2, 3 }.Concat(ex2), ex3 };
var res = xss.Catch();
var e = res.GetEnumerator();
HasNext(e, 0);
HasNext(e, 1);
HasNext(e, 2);
HasNext(e, 3);
AssertThrows<MyException>(() => e.MoveNext(), ex => ex == e3);

Concat

Ix.NET Concat

Ix.NET ConcatTest

Concat 方法将若干序列连接起来。

var res = new[]
{
new[] { 1, 2, 3 },
new[] { 4, 5 }
}.Concat();
// res == { 1, 2, 3, 4, 5 }
var i = 0;
var xss = Enumerable.Range(0, 3).Select(x => Enumerable.Range(0, x + 1)).Do(_ => ++i);
var res = xss.Concat().Select(x => i + " - " + x).ToList();
/*
res == {
"1 - 0",
"2 - 0",
"2 - 1",
"3 - 0",
"3 - 1",
"3 - 2",
}
*/
var res = EnumerableEx.Concat(
new[] { 1, 2, 3 },
new[] { 4, 5 }
);
// res == { 1, 2, 3, 4, 5 }

Create

Ix.NET Create

Ix.NET CreateTest

Create 方法使用协程创建序列。

private static IEnumerator<int> MyEnumerator()
{
yield return 1;
yield return 2;
}
var hot = false;
var res = EnumerableEx.Create<int>(() =>
{
hot = true;
return MyEnumerator();
});
// hot == false
var e = res.GetEnumerator();
// hot == true
HasNext(e, 1);
HasNext(e, 2);
NoNext(e);
hot = false;
var f = ((IEnumerable)res).GetEnumerator();
// hot == true
var xs = EnumerableEx.Create<int>(async yield =>
{
var i = 0;
while (i < 10)
{
await yield.Return(i++);
}
});
var j = 0;
foreach (var elem in xs)
{
// elem == j
j++;
}
// j == 10
var xs = EnumerableEx.Create<int>(async yield =>
{
var i = 0;
while (true)
{
if (i == 10)
{
await yield.Break();
return;
} await yield.Return(i++);
}
});
var j = 0;
foreach (var elem in xs)
{
// elem == j
j++;
}
// j == 10

Defer

Ix.NET Defer

Ix.NET DeferTest

Defer 方法使用返回序列的回调函数创建序列。

var i = 0;
var n = 5;
var xs = EnumerableEx.Defer(() =>
{
i++;
return Enumerable.Range(0, n);
});
// i == 0
// xs.ToList() == Enumerable.Range(0, n)
// i == 1
n = 3;
// xs.ToList() == Enumerable.Range(0, n)
// i == 2

Distinct / DistinctUntilChanged

Ix.NET Distinct / DistinctUntilChanged

Ix.NET DistinctTest

Ix.NET DistinctUntilChangedTest

Distinct 方法去除序列中的重复元素。

DistinctUntilChanged 方法去除序列中邻近的重复元素。

var res = Enumerable.Range(0, 10).Distinct(x => x % 5).ToList();
// res == Enumerable.Range(0, 5)
}
private class MyEqualityComparer : IEqualityComparer<int>
{
public bool Equals(int x, int y)
{
return x % 2 == y % 2;
} public int GetHashCode(int obj)
{
return EqualityComparer<int>.Default.GetHashCode(obj % 2);
}
}
var res = Enumerable.Range(0, 10).Distinct(x => x % 5, new MyEqualityComparer()).ToList();
// res =={ 0, 1 }
var res = new[] { 1, 2, 2, 3, 3, 3, 2, 2, 1 }.DistinctUntilChanged().ToList();
// res == { 1, 2, 3, 2, 1 }
var res = new[] { 1, 1, 2, 3, 4, 5, 5, 6, 7 }.DistinctUntilChanged(x => x / 2).ToList();
// res == { 1, 2, 4, 6 }

Do / DoWhile

Ix.NET Do / DoWhile

Ix.NET DoTest

Ix.NET DoWhileTest

Do 方法让序列在枚举元素时执行指定的函数。

DoWhile 方法通过模拟 do ... while 语句生成新的序列:无限次重复源序列中的所有元素直到指定条件不再满足为止。

var n = 0;
Enumerable.Range(0, 10).Do(x => n += x).ForEach(_ => { });
// n == 45
var n = 0;
Enumerable.Range(0, 10).Do(x => n += x, () => n *= 2).ForEach(_ => { });
// n == 90
var ex = new MyException();
var ok = false;
AssertThrows<MyException>(() =>
EnumerableEx.Throw<int>(ex).Do(x => { Assert.True(false); }, e => { Assert.Equal(ex, e); ok = true; }).ForEach(_ => { })
);
// ok == true
var obs = new MyObserver();
Enumerable.Range(0, 10).Do(obs).ForEach(_ => { });
// obs.Done == true
// obs.Sum == 45
private class MyObserver : IObserver<int>
{
public int Sum;
public bool Done; public void OnCompleted()
{
Done = true;
} public void OnError(Exception error)
{
throw new NotImplementedException();
} public void OnNext(int value)
{
Sum += value;
}
}
var sum = 0;
var done = false;
Enumerable.Range(0, 10).Do(x => sum += x, ex => { throw ex; }, () => done = true).ForEach(_ => { });
// done == true
// sum == 45
var x = 5;
var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
// res == { 5, 4, 3, 2, 1 }
var x = 0;
var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
// res == { 0 }

Expand

Ix.NET Expand

Ix.NET ExpandTest

var res = new[] { 0 }.Expand(x => new[] { x + 1 }).Take(10).ToList();
// res == Enumerable.Range(0, 10)
var res = new[] { 3 }.Expand(x => Enumerable.Range(0, x)).ToList();
var exp = new[] {
3,
0, 1, 2,
0,
0, 1,
0
};
// res == exp

Finally

Ix.NET Finally

Ix.NET FinallyTest

var done = false;
var xs = Enumerable.Range(0, 2).Finally(() => done = true);
// done == false
var e = xs.GetEnumerator();
// done == false
HasNext(e, 0);
// done == false
HasNext(e, 1);
// done == false
NoNext(e);
// done == true
var done = false;
var xs = Enumerable.Range(0, 2).Finally(() => done = true);
// done == false
var e = xs.GetEnumerator();
// done == false
HasNext(e, 0);
// done == false
e.Dispose();
// done == true
var done = false;
var ex = new MyException();
var xs = EnumerableEx.Throw<int>(ex).Finally(() => done = true);
// done == false
var e = xs.GetEnumerator();
// done == false
try
{
HasNext(e, 0);
Assert.True(false);
}
catch (MyException ex_)
{
Assert.Same(ex, ex_);
}
// done == true

ForEach

Ix.NET ForEach

Ix.NET ForEachTest

ForEach 方法枚举序列,为每一个元素调用指定函数,有不带下标和带下标两个版本。

var n = 0;
Enumerable.Range(5, 3).ForEach(x => n += x);
// n == 5 + 6 + 7
var n = 0;
Enumerable.Range(5, 3).ForEach((x, i) => n += x * i);
// n == 5 * 0 + 6 * 1 + 7 * 2

For

Ix.NET For

Ix.NET ForTest

For 方法枚举源序列,将每一个元素都映射为一个序列,然后连接这些序列。

var res = EnumerableEx.For(new[] { 1, 2, 3 }, x => Enumerable.Range(0, x)).ToList();
// res == { 0, 0, 1, 0, 1, 2 }

Generate

Ix.NET Generate

Ix.NET GenerateTest

Generate 方法通过模拟 for 循环来生成序列。

var res = EnumerableEx.Generate(0, x => x < 5, x => x + 1, x => x * x).ToList();
// res == { 0, 1, 4, 9, 16 }

Hide

Ix.NET Hide

Ix.NET HideTest

Hide 方法隐藏序列的真实类型。

var xs = new List<int> { 1, 2, 3 };
var ys = xs.Hide();
// ys is not List<int>
// xs == ys

If

Ix.NET If

Ix.NET IfTest

If 方法根据给定条件(谓词函数)的结果

  1. 在两个给定序列中选择其中之一。
  2. 在给定序列和空序列中选择其中之一。
var x = 5;
var res = EnumerableEx.If(() => x > 0, new[] { +1 }, new[] { -1 });
// res.Single() == +1
x = -x;
// res.Single() == -1
var x = 5;
var res = EnumerableEx.If(() => x > 0, new[] { +1 });
// res.Single() == +1
x = -x;
// res.IsEmpty() == true

IgnoreElements

Ix.NET IgnoreElements

Ix.NET IgnoreElementsTest

IgnoreElements 方法将源序列转换为空序列。

var n = 0;
Enumerable.Range(0, 10).Do(_ => n++).IgnoreElements().Take(5).ForEach(_ => { });
// n == 10

IsEmpty

Ix.NET IsEmpty

Ix.NET IsEmptyTest

IsEmpty 方法判断序列是否为空。

// Enumerable.Empty<int>().IsEmpty() == true
// new[] { 1 }.IsEmpty() == false

Max / MaxBy

Ix.NET Max / MaxBy

Ix.NET MaxTest

Ix.NET MaxByTest

Max / MaxBy 方法返回序列中的最大值。

Max 带有一个用于比较序列中元素的 comparer 参数(IComparer 接口的实例)。

MaxBy 带有一个用于转换序列中元素的 keySelector 参数(回调函数)。

private class Mod7Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
return Comparer<int>.Default.Compare(x % 7, y % 7);
}
}
// new[] { 2, 5, 3, 7 }.Max(new Mod7Comparer()) == 5
var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MaxBy(x => x % 3);
// res == { 2, 5, 2 }

Memoize

Ix.NET Memoize

Ix.NET MemoizeTest

Min / MinBy

Ix.NET Min / MinBy

Ix.NET MinTest

Ix.NET MinByTest

Min / MinBy 方法返回序列中的最小值。

Min 带有一个用于比较序列中元素的 comparer 参数(IComparer 接口的实例)。

MinBy 带有一个用于转换序列中元素的 keySelector 参数(回调函数)。

private class Mod3Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
return Comparer<int>.Default.Compare(x % 3, y % 3);
}
}
// new[] { 5, 3, 7 }.Min(new Mod3Comparer()) == 3
var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MinBy(x => x % 3);
// res == { 0, 3, 6 }

OnErrorResumeNext

Ix.NET OnErrorResumeNext

Ix.NET OnErrorResumeNextTest

OnErrorResumeNext 方法将若干序列连接起来,忽略序列中抛出的异常。

var xs = new[] { 1, 2 };
var ys = new[] { 3, 4 };
var res = xs.OnErrorResumeNext(ys);
// res == { 1, 2, 3, 4 }
var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
var ys = new[] { 3, 4 };
var res = xs.OnErrorResumeNext(ys);
// res == { 1, 2, 3, 4 }
var xs = new[] { 1, 2 };
var ys = new[] { 3, 4 };
var zs = new[] { 5, 6 };
var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
// res == { 1, 2, 3, 4, 5, 6 }
var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
var ys = new[] { 3, 4 };
var zs = new[] { 5, 6 };
var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
// res == { 1, 2, 3, 4, 5, 6 }
var xs = new[] { 1, 2 };
var ys = new[] { 3, 4 };
var res = new[] { xs, ys }.OnErrorResumeNext();
// res == { 1, 2, 3, 4 }
var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
var ys = new[] { 3, 4 };
var res = new[] { xs, ys }.OnErrorResumeNext();
// res == { 1, 2, 3, 4 }

Publish

Ix.NET Publish

Ix.NET PublishTest

Repeat

Ix.NET Repeat

Ix.NET RepeatTest

EnumerableEx.Repeat(n) 返回由元素 n 组成的无限序列。

x.Repeat() 返回由序列 x 中的所有元素无限次重复而生成的序列。

x.Repeat(n) 返回由序列 x 中的所有元素经过 n 次重复生成的序列。

var xs = EnumerableEx.Repeat(42).Take(1000);
// xs.All(x => x == 42) == true
// xs.Count() == 1000
var i = 0;
var xs = new[] { 1, 2 }.Do(_ => i++).Repeat();
var res = xs.Take(10).ToList();
// res.Count == 10
// res.Buffer(2).Select(b => b.Sum()).All(x => x == 3) == true
// i == 10
var i = 0;
var xs = new[] { 1, 2 }.Do(_ => i++).Repeat(5);
var res = xs.ToList();
// res.Count == 10
// res.Buffer(2).Select(b => b.Sum()).All(x => x == 3) == true
// i == 10

Retry

Ix.NET Retry

Ix.NET RetryTest

var xs = Enumerable.Range(0, 10);
var res = xs.Retry();
// res == xs
var xs = Enumerable.Range(0, 10);
var res = xs.Retry(2);
// res == xs
var ex = new MyException();
var xs = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex));
var res = xs.Retry(2);
var e = res.GetEnumerator();
HasNext(e, 0);
HasNext(e, 1);
HasNext(e, 0);
HasNext(e, 1);
AssertThrows<MyException>(() => e.MoveNext(), ex_ => ex == ex_);

Return

Ix.NET Return

Ix.NET ReturnTest

Return 方法返回由一个元素组成的序列。

// EnumerableEx.Return(42).Single() == 42

Scan

Ix.NET Scan

Ix.NET ScanTest

Scan 方法转换序列:

  • Scan 带有一个有返回值的二元函数和一个可选的初值。
  • 结果序列的第 1 项没有初值时等于源序列的第 1 项,有初值时等于将二元函数应用到初值和源序列的第 1 项后所得到的结果。
  • 结果序列的第 n + 1 项等于将二元函数应用到结果序列的第 n 项和源序列的第 n + 1 项后所得到的结果。
var res = Enumerable.Range(0, 5).Scan((n, x) => n + x).ToList();
// res == { 1, 3, 6, 10 }
var res = Enumerable.Range(0, 5).Scan(10, (n, x) => n - x).ToList();
// res == { 10, 9, 7, 4, 0 }

SelectMany

Ix.NET SelectMany

Ix.NET SelectManyTest

SelectMany 方法将源序列中的所有元素都映射成指定序列,然后连接这些序列。

var res = new[] { 1, 2 }.SelectMany(new[] { 'a', 'b', 'c' }).ToList();
// res == { 'a', 'b', 'c', 'a', 'b', 'c' }

Share

Ix.NET Share

Ix.NET ShareTest

SkipLast

Ix.NET SkipLast

Ix.NET SkipLastTest

SkipLast 方法略过序列尾部的 n 个元素,返回其余元素组成的序列。

var e = Enumerable.Range(0, 5);
var r = e.SkipLast(3).ToList();
// r == e.Take(2)

StartWith

Ix.NET StartWith

Ix.NET StartWithTest

StartWith 方法在序列之前插入指定的(1 个或多个)元素。

var e = Enumerable.Range(1, 5);
var r = e.StartWith(0).ToList();
// r == Enumerable.Range(0, 6)

TakeLast

Ix.NET TakeLast

Ix.NET TakeLastTest

TakeLast 方法返回由序列尾部的 n 个元素组成的序列。

var e = Enumerable.Range(0, 5);
var r = e.TakeLast(3).ToList();
// r == e.Skip(2)

Throw

Ix.NET Throw

Ix.NET ThrowTest

Using

Ix.NET Using

Ix.NET UsingTest

While

Ix.NET While

Ix.NET WhileTest

While 方法通过模拟 while 语句生成新的序列:只要指定条件满足就无限次重复源序列中的所有元素。

var x = 5;
var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
// res == { 5, 4, 3, 2, 1 }
var x = 0;
var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
// res == { }

ReactiveX 学习笔记(11)对 LINQ 的扩展的更多相关文章

  1. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  2. python3.4学习笔记(三) idle 清屏扩展插件

    python3.4学习笔记(三) idle 清屏扩展插件python idle 清屏问题的解决,使用python idle都会遇到一个常见而又懊恼的问题——要怎么清屏?在stackoverflow看到 ...

  3. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  4. Ext.Net学习笔记11:Ext.Net GridPanel的用法

    Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...

  5. SQL反模式学习笔记11 限定列的有效值

    目标:限定列的有效值,将一列的有效字段值约束在一个固定的集合中.类似于数据字典. 反模式:在列定义上指定可选值 1. 对某一列定义一个检查约束项,这个约束不允许往列中插入或者更新任何会导致约束失败的值 ...

  6. golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好

    golang学习笔记11   golang要用jetbrain的golang这个IDE工具开发才好  jetbrain家的全套ide都很好用,一定要dark背景风格才装B   从File-->s ...

  7. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  8. Python3+Selenium3+webdriver学习笔记11(cookie处理)

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记11(cookie处理)'''from selenium im ...

  9. 并发编程学习笔记(11)----FutureTask的使用及实现

    1. Future的使用 Future模式解决的问题是.在实际的运用场景中,可能某一个任务执行起来非常耗时,如果我们线程一直等着该任务执行完成再去执行其他的代码,就会损耗很大的性能,而Future接口 ...

  10. 《C++ Primer Plus》学习笔记11

    <C++ Primer Plus>学习笔记11 第17章 输入.输出和文件 <<<<<<<<<<<<<< ...

随机推荐

  1. [UE4]多线程开关,开启的解决方案

    像这样直接获取值就会被警告. 解决方法:定义一个变量speed,然后在“Blueprint Update Animation”事件中赋值给这个变量. 这样就不会被警告了. 另外一种解决方法:就是关掉多 ...

  2. 00013 - top命令详解

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. top显示系统当前的进程和其他状况,是一个动态显示过程,即可以通过用户按键来不 ...

  3. Angular2 入门详解

    AngularJS 2 快速入门 npm是什么?   npm其实是Node.js Package Manager的简称,是Node.js包管理工具(package manager) 安装Node.js ...

  4. C# 自己动手实现Spy++(一)

    因为项目要用到获取其他程序的标题,就想到了用Spy++,但是它是一个工具,并没有C#的源代码,所以就想探索下他的原理,网上搜索了下spy++的源代码,找到了一篇:http://blog.csdn.ne ...

  5. mysql视图 触发器 事物 函数 存储过程

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  6. JavaScript基础知识点学习记录

    一.简介: JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言,同时也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如相应用户的各种操作. J ...

  7. appium 搭建及实例

    一.Appium环境搭建(Java版本) 转载2016-04-26 09:24:55 标签:appium移动端自动化测试 市场需求与职业生涯的碰撞,阴差阳错我就跨进了移动App端自动化测试的大门,前生 ...

  8. 【Jmeter自学】Jmeter性能测试(四)

    ==================================================================================================== ...

  9. 遇到的问题&思考

    MYSQL需要批量修改表前缀: http://jingyan.baidu.com/article/11c17a2c742561f446e39d2f.html Select CONCAT( 'ALTER ...

  10. 部署django项目,sqlite3数据库出错sqlite3.NotSupportedError: URIs not supported

    如果遇到这个错误 sqlite3.NotSupportedError: URIs not supported 修改类似 该路径 的 base.py文件 /root/.virtualenvs/fkPy3 ...